futureスペックのjs: trueなテストが動かない時 解決編
Rails4.1アップデートの過程でjs: trueなテストがこけるようになっていた原因がわかった。
js: trueのテストの時、usersテーブルに入っているはずのレコードが空になっていて、ログインできずに目的の要素を発見できずにビジーループからのタイムアウトが起きていた。
なんでusersテーブルが空に見えていたかというと、js: trueにすると裏でちゃんとブラウザが立ち上がって、別プロセスでRailsアプリをちゃんと叩くようになるんだけど、
js: trueを使っていない普通のrspecテストとは別プロセスでデータベースを接続することになる。
rspecのデフォ設定だと、テスト毎にトランザクションが始まってテストが終わったらロールバックするようになってる。
コミットしないとほかのコネクションから見えないので、js: trueテストからは上記のようにusersテーブルが空に見えていた。
解決方法は、テスト実行時にトランザクションを使わない。
下記use_transactional_fixturesにfalseを設定すれば、トランザクションは使わなくなる。
# spec/spec_helper.rb ..... config.use_transactional_fixtures = false .....
トランザクションを使わないと、テストを実行する度データが溜まっていき、すぐに一意制約に違反するのでテスト毎にデータベースを空にしないといけない。
そこでhttps://github.com/bmabey/database_cleanerの登場になる。
database_cleanerを使えばテストを実行する度に空にしてくれるようになる。
でも今のアプリのテストにはマスターデータ必要だし、遅い(らしい)し、ドキュメント見ないと構文がわからなかったのでspec_helperにデータベースを奇麗にするのを書いてみた。
テーブル数によるけど今はこれで十分早い感じ。
ActiveRecord::Base.connection.tables.each do |table| next if table == 'schema_migrations' ActiveRecord::Base.connection.execute("delete from #{table}") # sequenceも初期化したいほうがいいかも end
テスト通りました。
ttp://www.oiax.jp/rails/zakkan/testing_javascript_with_rspec_and_capybara.html
ttp://aligach.net/diary/20120209.html