Turnip を使ったテスト作成のノウハウ
現在、バリバリと Tunip + Capyabara + PhantomJS (poltergeist) で end-to-end テストを書いてます。 そこで知ったノウハウを書きます、今回はテストの構成分けなどの上流側ではなく、ツールや steps 側になります。
Turnipに限らず Cucmber, RSpec Feature など Capybara を使った、テストの大部分は
の繰り返しです。
ツール
Chrome等のDevTools
まずDOM上のエレメントを特定するための正しく、かつメンテンス生の高いCSSセレクターを決めないと行けません。これは ブラウザーの開発ツール (Cmd+Opt+I)のElements画面で、エレメント選択(Cmd+Shift+C)で画面上の目的の場所をクリックして目的の CSSセレクター を探していけると思います。
また開発ツールの Console を使うと、document.querySelector() や jQuery でCSSセレクターが 正しいかを確認できます。 よくあるのは CSSセレクターがユニークでは無く違う要素が選択されてしまう事があるで、単純なCSSセレクター以外は試してみるのが良いです。
正し、jQueryのCSSセレクターには拡張があります、これはCapybaraでは動作しないので注意して下さい。
Snapshot
テストが上手く行かない時は表示要素の特定用CSSセレクターの間違だけではなく、対象のページまで来てなかったりJavaScriptが正しく動作してないなどの事もよくあります。 Capybara-WebkitやPoltergeistには現在のDOM(画面)を画像やHTMLとして保存できます。
これを使い以下のようなメソッドやstepsを定義すると、stepsの中や feature の中から呼び出す事で画面を確認できます。
- helper
def take_screenshot(save_type = :image, path = nil) path = Time.now.strftime("/tmp/%y%m%d-%H%M%S-%L.png") unless path if save_type == :image page.save_screenshot(path) else File.write(path, page.html) end end
- steps
step 'HTML保存' do take_screenshot(:html) end step '画面画像保存' do take_screenshot end
失敗時の Snapshot
以下のような設定を書くと、テストが失敗した時に自動的に Snapshot をとる事ができ失敗の原因追求にとても役立ちます。
RSpec.configure do |config| ・・・ config.after(type: :feature) do |example| DatabaseCleaner.clean take_screenshot if example.exception.present? end
ログ出力
steps は Ruby のコードなので、 p 等でデバック情報をコンソールに出力出来ます。
また、テスト対象の画面にあるJavaScript中に console.log() を書くとやはりコンソールに出力されるのでAjaxからみの複雑な機能のテスト作成に役立ちます。
steps ノウハウ
findの match オプション
page.find()メソッドはデフォルトでは多数がマッチするとエラーになります。CSSセレクターを工夫することでも対処しなくとも、絶対に最初にマッチしたものが正解の場合は以下のように match オプションを指定して逃げる事も出来ます。
page.find("form input[name='email']", match: :first)
findの visible オプション
page.find()メソッドはデフォルトでは表示されている要素しかマッチしませんが、非表示の要素の値を変更したい場合がありますが、そのような場合は以下のように visible オプションを指定することで可能になります。
page.find("form input[name='email']", visible: :all)
他のステップの利用
step はrubyのメソッドでは無いので、単純には呼び出せませんが、 Calling steps from other steps に書いてあるように、
の2つを適宜、使い分けると良いと思います。
step 'メール :email パスワード :password ででログイン' do |email, password| ... end step '社員Aのログイン' do step "メール 'a@kaisya.com' パスワード 'PDB4oq4X' ででログイン" end step 'ある社員のログイン' do send 'メール :email パスワード :password ででログイン', "e#{rand(1000)}@kaisya.com", "PDB4oq4X" end
その他
画面サイズ
アプリによってはCapyabara-Webkit画面サイズ(1024 x 768)では一部表示されない場合があるかもしれません。画面サイズは以下のようにして指定できます。
Capybara.register_driver :poltergeist do |app| Capybara::Poltergeist::Driver.new(app, window_size: [1280, 1024]) end
ここに書いたノウハウは、検索すると stackoverflow, qiita, ブログ等に書かれています。それらの情報を書いて頂いた方に感謝いたします。