capybara-webkitを使ってインテグレーションテストする方法を探す
弊社でもAjax的なプログラミングを少しずつ始めていまして、ちゃんとインテグレーションテストする方法が欲しくなってきたところでした。で、いろいろ見てみると、capybara-webkitとか言うのが良さそう。
でも、ちゃんとテストできるまで、なんか妙に苦労したのでその話をします。あと基本的には、例によってCapybaraのREADMEを隅から隅まで読めば全部書いてあるので、ちゃんと読んだほうが良いかもしれません。
References
ぼくのかんがえたさいきょうのtest_helper
Capybara.default_driver = :rack_test class ActionDispatch::IntegrationTest include Capybara::DSL self.use_transactional_fixtures = true def self.test_with_js self.use_transactional_fixtures = false setup do Capybara.current_driver = :webkit DatabaseCleaner.strategy = :truncation DatabaseCleaner.start end teardown do DatabaseCleaner.clean Capybara.use_default_driver end end setup do Capybara.reset_sessions! # 適当に初期化する end teardown do # 適当に掃除する end end
JSが必要なインテグレーションテストをするときはtest_with_jsを呼んでおく。全部webkitでやるとすごい遅いよ!特定のテストだけやる方法もあると思うけど、まあいいや。
class HelloHelloTest < ActionDispatch::IntegrationTest self.test_with_ajax test "JS is enabled" do assert_equal 3, page.evaluate_script("1+2") end end
いちおうGemfileも書いておこう。
gem 'capybara' gem 'capybara-webkit', :git => "git://github.com/thoughtbot/capybara-webkit.git" gem 'database_cleaner'
最初はAkephalosを使おうとした
なんか文字化けするので止めた。あと、Capybaraの新しいやつとうまく動かない気配があったので。
ただ、良く考えてみると、Gemfileに:git => ...と書く方法を試していないので、新しいバージョンだといろいろ良かったのかもしれない。まあめんどくさいしいいや。
DBがからっぽになる問題
まず、適当にintegration testの中からモデルを触っているとぶつかるのがこの問題だと思う。
:webkitとか:akephalosとか、とにかく:rack_test以外のドライバを使うときは、Webサーバが別のスレッドで動くので、トランザクション?とかの関係でこうなる。
class ActionDispatch::IntegrationTest self.use_transactional_fixtures = false end
すると良い。また、DatabaseCleanerを使ってリセットするのが常套手段のようなので、それも設定しておく。
:remote => trueななんかをしてから処理が終わる前に次にいっちゃう問題
Capybaraのほうでうまいことやってくれてるらしいんだけど、微妙に制限がある。
def assert_list_are(list) assert_equal list, all("#list li").map(&:text) end
とかやってたらうまくいかなかった。findを使うと待つよ!と書いてあったので、
def assert_list_are(list) messages = list.map.with_index {|message, index| find("#list li:nth-child(#{index+1})").text } assert_equal list, messages end
こんな感じにしたら、とりあえずうまく動いてた。
:webkit使うとうまくいかないテストがあった
なんでだかよくわからないんだけど、visitしたあとに返ってこない系で、しびれを切らしてCtrl-Cするやつがあった。全部webkitでやらないのは、それも理由。
ただし正直なところまだあんまりわかってない
かんたんなプロジェクトを作っていろいろ試行錯誤した。
本物のプロジェクト(つまりユビレジのことだけど)では、とりあえずevaluate_scriptが動くことだけ確認してあって、実際にAjaxのテストはまだやってない。
どうでも良いけど、websocketのテストとかどうするんだろうな。専用の環境を作ればなんとかなるんだろうか。