CucumberとCapybaraでシナリオ失敗時にスクリーンショットを撮る

Cucumber + Capybaraの環境で、CucumberのシナリオがFailした時にスクリーンショットを取る方法です。

スクリーンショット取得の設定方法

「features/support」ディレクトリ配下に以下の内容でファイルを作成する。

```ruby

features/support/screenshot.rb

After(‘@javascript’) do |scenario| if scenario.fialed? page.driver.browser.save_screenshot(“html-report/#{scenario.id}.png”) embed(“#{scenario.id}.png”, “image/png”, “SCREENSHOT”) end end

「html-report」ディレクトリを作成しておく。

以下のオプションでcucumberを実行する。

```bash $ cucumber –format html –out html-report/index.html

「html-report/index.html」をブラウザで開くとテストレポートが表示されます。

シナリオが失敗した箇所に「SCREENSHOT」のリンクが表示され、クリックすると画像を確認できます。お手軽な割にリッチなレポートになるので、初めてやると感動しますね。

補足

上記の設定についての補足です。

Before/Afterフック

Cucumberでは、Before/Afterフックを使って各シナリオの実行の前後に特定の処理を実行します。上記のコードではAfterフックでシナリオ実行後の処理を指定しています。

Taggedフック

Before/Afterの引数にタグを与えることで、Cucumberは特定のタグがついたシナリオのみを対象に処理を実行します。上記のコードではAfterフックに@javascriptタグを与えることで、「@javascript」のタグがついたシナリオの後にのみ処理を実行します。

@javascriptタグ

Capybaraは通常rack-testを通じてIn-Processアプローチでテストを実行します。しかし、In-ProcessアプローチではJavaScriptを利用したページのテストができません。そこでJavaScriptを利用するシナリオには@javascriptタグを指定します。

Capybaraは、@javascriptタグがついたシナリオを見つけるとOut-of-Processでテストを実行します。デフォルトではSeleniumを利用してブラウザを操作します。

スクリーンショットを取得する場合、ブラウザを使用することが前提になるため、上記のコードでは@javascriptタグで対象のシナリオを絞り込んでいます。

scenarioオブジェクト

Before/Afterフックはブロック引数にscenarioオブジェクトを引き渡します。scenarioオブジェクトにはシナリオ名、ID、シナリオの正否などが含まれます。上記のコードでは、scenario.faild?でシナリオの正否を判定しています。

Selenium, save_screenshot

page.driver.browserでSeleniumのbrowserオブジェクトにアクセスし、save_screenshotでスクリーンショットを取得します。

embedメソッド

embedメソッドは、ファイル名、MIMEタイプ、ラベルの3つの引数を取り、HTML形式の出力に対してファイルを紐づけます。

上記のコードでは、スクリーンショットのpngファイルを「SCREENSHOT」というラベルでレポートに紐づけています。ラベルはレポート中のリンクテキストになります。

{% amazon text 1934356808 %}

{% amazon medium_image 1934356808 %}