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