プログラマでありたい

おっさんになっても、プログラマでありつづけたい

Capybara-DSLのはなし

 ちょっとCapybaraについて、整理する必要があったのでこちらで簡単にまとめておきます。Capybaraは、Githubのスタートページに使い方が丁寧に書いているので、そちらを参照したら大抵のことが解るようになっています。

What is Capybara



 Capybaraは、Webアプリケーションのインテグレーション・テストを補助する為のライブラリです。Capybaraが提供する本質的な機能としては、DSLとDriverの2点のみです。DSLとはドメイン固有言語で、特定の問題に特化したコンピュータ言語です。Capybaraはテスティングフレームワークを操作する命令を、それぞれのフレームワークに依存しない形で提供します。つまり、テスティングフレームワークであるCucumberやRSpec,Test::Unitなどを透過的に利用できます。次にドライバーです。Webアプリケーションのインテグレーション・テストには、ブラウザもしくはそれに類するものが必要です。その為に、Seleniumのようにブラウザを操作するフレームワークや、WebKitのようなブラウザのレンダリングエンジンを直接使う方法があります。Capybaraは、それらをドライバとして扱うことが出来ます。

CapybaraのDSL



 Capybaraには、下記の機能をDSLとして提供しています。要は、CucumberであろうがRSpecであろうが、同じように扱えるところがメリットです。一方で、CucumberからRSpecに乗り換えるという要件もあまりないので、どう考えるべきなんでしょうね。

画面遷移機能

 Capybaraの画面遷移は、GETメソッドのみです。POSTについては、フォーム入力機能を利用します。

メソッド名 機能
visit GETでページ遷移します。カレントのパスは、current_pathで取得できます。
リンク&クリック機能

Capybaraは、一通りのフォームの入力機能が用意されています。

メソッド名 機能
click_link('id-of-link') ID指定でリンクを押します
click_link('Link Text') リンクのテキスト名で押します
click_button('Save') ボタン名で名前を押します
click_on('Link Text') リンクかボタンどちらかをクリックします
click_on('Button Value') ボタンの値指定で押します
フォーム入力機能

Capybaraは、一通りのフォームの入力機能が用意されています。

メソッド名 機能
fill_in('First Name', :with => 'John') フォームテキストを埋めます
fill_in('Password', :with => 'Seekrit') パスワードフォームを埋めます
fill_in('Description', :with => 'Really Long Text...') TextAreaを埋めます
choose('A Radio Button') ラジオボタンを選択します。
check('A Checkbox') チェックボタンを選択します。
uncheck('A Checkbox') チェックボタンの選択を外します
attach_file('Image', '/path/to/image.jpg') 画像を添付します
select('Option', :from => 'Select Box') セレクトボックスを選択します
クエリー機能(確認機能)

Capybaraではクエリー機能を利用して、テストを行います。

メソッド名 機能
page.has_selector?('table tr') エレメントの存在確認をします
page.has_selector?(:xpath, '//table/tr') XPath指定で、エレメントの存在確認をします
page.has_xpath?('//table/tr') XPath指定で、エレメントの存在確認をします
page.has_css?('table tr.foo') CSSで、エレメントの存在確認をします
page.has_content?('foo') 文字列の存在確認をします
検索機能

検索機能としては、find_field,find_button,find,allの4つがあります。

メソッド名 機能
find_field('First Name').value フィールド名指定で検索し、値を表示します
find_link('Hello').visible? フィールド名指定で検索し、表示有無を確認します
find_button('Send').click ボタンを検索し、クリックします
find(:xpath, "//table/tr").click XPath指定で検索し、クリックします
find("#overlay").find("h1").click 入れ子で検索し、クリックします
all('a').each { |a| a[:href] } 全ての要素からaタグを抽出し、hrefを表示します
スコープ機能

 スコープ機能を利用することで、特定のエレメント下のみ操作できます。ループ処理等で便利です。

within("li#employee") do
  fill_in 'Name', :with => 'Jimmy'
end

within(:xpath, "//li[@id='employee']") do
  fill_in 'Name', :with => 'Jimmy'
end
スクリプティング機能(JavaScriptのサポート)

 CapybaraはJavaScriptをサポートしています。ただし、使用中のDriverがJavaScriptをサポートしていることが前提です。(O.K. Selenium,WebKit,Poltergeist NG RackTest)

メソッド名 機能
page.execute_script("$('body').empty()") JavaScriptを実行します
デバッグ機能

 デバッグ用に幾つかの機能が提供されています。テストのエビデンスにも活用出来るのでは。(テストの再現性を確保したら、そもそもエビデンス不要ですがね。)

メソッド名 機能
save_and_open_page スクリーンショットを取得します
print page.html ページの印刷します
page.save_screenshot('screenshot.png') スクリーンショットを取得します

CapybaraのDriver



 Capybaraには、Driverとして幾つかのブラウザシミュレータやブラウザエンジンを扱うことが出来ます。使い分けとしては、JavaScriptを利用しないものについては、RackTestのような軽量のものを利用することが考えられます。また、開発段階は、Seleniumを使って実際の動きを見て、退行テストの段階になったときはWebKitを使い軽量化するなども考えられます。下記のように、簡単にDriverを変更できます。

Capybara.default_driver = :selenium
Driver名 特徴
RackTest デフォルトのDriverです。JavaScriptはサポートしていません。また、外部のURLへのアクセスも出来ません。
capybara-mechanize RackTestと同様にJavaScriptはサポートしていません。しかし、外部のURLへのアクセス可能です。
Selenium Capybaraは、Selenium 2.0(WebDriver)をサポートしています。またJavaScriptをOnにした場合は、指定しないと自動的にSeleniumを利用します。
Capybara-webkit headlessを利用して画面なしでテストします。レンダリングエンジンとしては、WebKitを利用しJavaScriptのテストが可能です。Xvfbが必要です。
Poltergeist headlessを利用して画面なしでテストします。PhantomJSが動作しJavaScriptのテストが可能です。Xvfbが不要です。


 サーバにXvfbのインストールは、割と面倒くさいです。継続的インテグレーションの為にサーバサイドでテストを実行したい場合は、Poltergeistがよいかもしれません。本格的にやるのであれば、Seleniumを利用して、複数のブラウザに対してテストを実行するといったこともよいですね。

まとめ



 Capybaraの役割が解れば、なかなか便利です。私の場合は、SeleniumやCucumber,RSpecを使ってからCapybaraを使いだしました。いきなりCapybaraの方が学習コストが低くてよいかもしれません。一方で、ハマった時によくわからないというのもあるかもしれません。何はともあれ、一度お試しください。Enjoy!!


See Also:
Web画面の自動テストの導入に失敗する理由とその対策
Selenium2.0 WebDriverで複数ブラウザのUIテスト もう一度、Selenium再入門
JenkinsとSelenium WebDriverでUI層のテストも自動化&永続化する


参照:
jnicklas/capybara