はじめに
前提
seed データを投入し /tasks
にアクセスしたら seed データが表示されている状態
前回 のあらすじ
- 景気良く RSpec をインストールし、テストファイルを作成する
- controller の機能テストを行いたく
spec/controller/
配下にテストファイルを移動 - 紆余曲折し、capybara の存在を知る
- エラーにより利用出来ず capybara から手を引く
Bad End
前回やりたかったこと
-
/
(ルートページ) にアクセスし、同じく seed データ一覧を表示 -
/tasks
にアクセスし、 seed データ一覧を表示
今回はそれのリベンジマッチです。
困り果てていたら、ヒントをいくつか頂きました。
ヒントを元にこの記事を書きながら強くなっていこうと思います
それでは、はじまりはじまり
1. 準備
capybara さんとお別れをします。
さっぱり綺麗に忘れることが出来ないので、
$ git commit -m 'bad end by capybara'
capybara との思い出に『名前をつけて保存する』をする。
そして
- #require 'capybara/rails'
- #require 'capybara/rspec'
require 'rails_helper'
これだけにする
あいつの顔はしばらく見たくないです...
2. Who is SystemSpec ?
あしたのために(その1) : SystemSpec を知るべし
まずこの人は誰で何ができるのでしょうか
2.1 再会は突然に
公式 を見つけれました
ん?
visit "hoge"
????
おいおいおいおい ま 待ってくれ!!!
こいつ、、こいつ capybara じゃねえかよ!!!
知ってます!私こいつ知ってますよ!
トラウマ(僕のQiita記事) と トラウマ(公式)
なんてこった、前回どん詰まりした visit method を使うなんて...
💡(・□・;)ハッ!
いや待てよ、 、、
もしかして、 System Spec を使えば capybara とやり直せる?
そうとわかれば話が早い
使いましょう使いましょうすぐ使いましょう
2.2 How to use System Spec
いくつかルールがあるみたいでした
- describe に
:type => :system
と記載すべし -
spec/system/
に配置すべし - before に
driven_by(:rack_test)
を記載すべし
あれ?なんか デジャブ
ルールの1と2って被ってないか?そんな予感がする
よし、ルール1を無視してみよう
2.3 Let's try
Before
RSpec.describe TasksController do
render_views
before do
`rails db:reset RAILS_ENV=test`
end
context 'show index' do
it 'show task list on index page' do
get :index
expect(response).to render_template('index')
expect(response.body).to include 'task 001 : hogehoge'
end
end
end
After
RSpec.describe TasksController do
before do
driven_by(:rack_test)
`rails db:reset RAILS_ENV=test`
end
context 'show index' do
it 'show tasks list on index page' do
visit '/tasks'
assert_selector 'h1', text: 'Your Tasks'
assert_text 'task 001 : hogehoge'
end
end
end
テストの書き方は System Spec の公式様が
system tests.
We encourage you to familiarize yourself with their documentation.
(うるせえこれ読んどけ)
と仰ったので、読んでみたら書いてありました
ちなみに 日本語版 もあるみたい
Finished in 8.1 seconds (files took 8.62 seconds to load)
1 example, 0 failures
わ、動いた。
しかも成功した....成功した!!!!
成功した!!!(大興奮)
大歓喜すぎて実験結果の記載を忘れるところでした
System Spec を使うとき、
spec/system/
以下にある xxx_spec.rb
ファイルには
:type => :system
の記載は不要である!!!
勉強になりました。
それと type と ディレクトリとディレクトリ名は深い繋がりがありそうです
あしたのために(その2) : 単語の意味を覚えよ
そういうこと????
いや、多分これだけじゃないな
2.4 テストを1つ完成させよう
it 'show tasks list on index page' do
visit '/tasks'
assert_selector 'h1', text: 'Your Tasks'
assert_text 'task 001 : hogehoge'
assert_text 'task 002 : fugafuga'
assert_text 'task 003 : piyopiyo'
end
なめてんのか、とどこからか声が聞こえます。
わかってます。
assert_text 'task 002 : fugafuga'
assert_text 'task 003 : piyopiyo'
この辺でしょ?
なんとかしますよ。。。いつか
まあ何はともあれ
# bundle exec rspec
.
Finished in 8.47 seconds (files took 6.81 seconds to load)
1 example, 0 failures
WRYYYYYYY!!!!
2.5 景気良くきましょう!2つ目も終わらせる
RSpec.describe TasksController do
before do
driven_by(:rack_test)
`rails db:reset RAILS_ENV=test`
end
context 'show index' do
it 'show tasks list on index page' do
visit '/tasks'
assert_selector 'h1', text: 'Your Tasks'
assert_text 'task 001 : hogehoge'
assert_text 'task 002 : fugafuga'
assert_text 'task 003 : piyopiyo'
end
it 'show tasks list on root page' do
visit '/'
assert_selector 'h1', text: 'Your Tasks'
assert_text 'task 001 : hogehoge'
assert_text 'task 002 : fugafuga'
assert_text 'task 003 : piyopiyo'
end
end
end
# bundle exec rspec
..
Finished in 17.47 seconds (files took 5.91 seconds to load)
2 examples, 0 failures
WRYYYYYYYーーーーッ!!!!!!!!
$ git commit -m 'happy end by system spec'
ところで、僕はなんで capybara が使えるようになっていたんでしょうか。。。
調べるものとして残しておく必要がありそうです。
3. テストデータの初期化
あしたのために(その3) : テストの度にDBの中身をリセットせよ
これは、毎回テストデータをリセットしないと、前提条件が一致しないからだそうです。
そりゃそうですよね、前回のテストデータが前提条件とかになったら、そのテスト単体で出来ないし
前提条件が必要ならテストの外で書かないといけないですよね。
それでは RSpec でのテストデータの中身の消し方を調べましょう
3.1 DatabaseCreaner とはなんぞや
あしたのために(その3)には続きが
あしたのために(その3) :
テストの度にDBの中身をリセットせよ
ただしRails 5.1 以降では DatabaseCreaner は不要
念の為、確認
# rails -v
Rails 5.2.2
5.1 以降ですね
要らない=知らないでよい
にはならないので、
不要なら不要になった理由を知る必要がありますね
Database Cleaner is a set of strategies for cleaning your database in Ruby.
(db を綺麗にするぜ)
名前の通りの人でした
3.2 DatabaseCreaner は要らない子?
書いてあることはめちゃくちゃ あしたのための(その3) の要件をクリアしてそうなんですけどね、
標準装備されたとかかな?
RSpec 3.7 has been released! ー 日本語訳
Feature Spec では、JavaScript が有効な Capybara ドライバー(Selenium や Poltergeist)を使った場合、 テストは Rails とは別のプロセスで実行されます。 その結果、テストプロセスと Rails プロセス間でデータベースのトランザクションが共有されないため、 RSpec 標準のデータベースロールバック機構を利用できず、 代わりに Database Cleaner のような gem を使う必要がありました。 Rails 開発チームは System Test でこのような問題が発生しないように実装をしました。 そのおかげで、System Spec では別の gem を利用することなく RSpec のロールバック機構を利用できます。
この人たちが頑張ったおかげで、要らなくなったってこと?
へ〜、で?
3.3 db:reset はだめ?
そもそも、
before do
driven_by(:rack_test)
`rails db:reset RAILS_ENV=test`
end
rails db:reset
で初期化されているのではなかろうか
これまでなんどもテストを実行してきた、ここでテスト環境の html をみてみる
(byebug) puts page.html
<!DOCTYPE html>
<html>
<head>
<title>Myapp</title>
<link rel="stylesheet" media="all" href="/assets/application-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.css" data-turbolinks-track="reload" />
<script src="/assets/application-3c2e77f06bf9a01c87fc8ca44294f3d3879d89483d83b66a13a89fc07412dd59.js" data-turbolinks-track="reload"></script>
</head>
<body>
<h1>Your Tasks</h1>
<ul>
<li>task 001 : hogehoge</li>
<li>task 002 : fugafuga</li>
<li>task 003 : piyopiyo</li>
</ul>
</body>
</html>
なんかちゃんと都度 reset が効いていそうに見える
終わり?
4. 完了...?
e2e テストが完了しました。
# bundle exec rspec
..
Finished in 13.11 seconds (files took 6.26 seconds to load)
2 examples, 0 failures
思ったのは、テストデータに seed を使うのは普通じゃないのかもしれない。
テストデータはテストデータで作成してするのが普通なのかもしれない。
task = Task.create(...)
とかで作ったら
save されたデータを削除しないといけない
= テストデータの中身をリセットする(昔はこれに DatabaseCreaner を使っていた?)
につながるのではないだろうか
今はすごいシンプルな形だから seed データで事足りてるけど
今後は、上記のようなケースにぶち当たりそうな気配を感じます。
あってるっぽい?
RSpecでテストDBに突っ込んだデータを消したい
宿題
ちょっと理解するのをスキップしたものリスト
- なんで System Spec の設定をしていたら、いつの間にか capybara が使えるようになっていたのか
- 「
driven_by(:rack_test)
」 これは何か - テストコードの
assert_text '..'
のあたりは、同じことを繰り返し行なっているので、うまいことやりたい - あしたのために(その2、3) を深める
あしたのために
あしたのために(その1) : SystemSpec を知るべし
あしたのために(その2) : 単語の意味を覚えよ
あしたのために(その3) : テストの度にDBの中身をリセットせよ
ありがとうございました!!