連載第5回では、「ステップ定義」の基本を解説し、NumberPickerを操作するためのステップ定義方法を紹介しましたが、ステップ定義には、他にもさまざまなものがあります。
Calabash-Androidでは、GPSを操作するための「ステップ定義」も用意されています。
効果 | テストシナリオ内での実際の記述方法 | ステップ定義 |
---|---|---|
指定した緯度・経度にGPSを設定する | When I am at 35.6102724, 139.7481288 | Then /^I am at ([-+]?[0-9]*\.?[0-9]+), ([-+]?[0-9]*\.?[0-9]+)$/ |
指定した緯度・経度にGPSを設定する | Then I go to 35.6102724, 139.7481288 | Then /^I go to ([-+]?[0-9]*\.?[0-9]+), ([-+]?[0-9]*\.?[0-9]+)$/ |
ちなみにアプリからGPSを操作するためには、「{プロジェクトのルート}/app/src/main/AndroidManifest.xml」ファイルに、下記の定義を追加する必要があります。
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Calabash-Androidには、下記のスクリーンショット撮影用の「ステップ定義」が用意されています。
テストシナリオ内での実際の記述方法 | ステップ定義 |
---|---|
Then take picture | Then /^take picture$/ |
Then I take a picture | Then /^I take a picture$/ |
Then I take a screenshot | Then /^I take a screenshot$/ |
これらを使用すると、プロジェクトのルートに、「screenshot_x.png」の名前でスクリーンショットの画像ファイルが作成されます(「screenshot_0.png」「screenshot_1.png」「screenshot_2.png」……のように、xの部分は0からインクリメントされます)。
・スクリーンショットファイルの出力先の指定
スクリーンショットファイルの出力先は、Calabash-Androidの実行時に下記手順で指定することも可能です。
$ SCREENSHOT_PATH=./result/ calabash-android run {YOUR_APK_FILE}
指定できるパスは、プロジェクトのルートからの相対パスです。指定するパスに相当するディレクトリは、事前に作成しておく必要があります。作成しておかないと、スクリーンショット撮影時にエラーとなります。
詳しくは、Screenshot locationも参考にしてください。
・テスト失敗時のスクリーンショットの自動撮影の停止方法
Calabash-Androidのデフォルト設定では、テスト失敗時にも自動的にスクリーンショットを撮影します。ファイル名および出力先は、上記と同じです。テストシナリオを作成途中の場合、この画像ファイルがどんどん増えてきて邪魔になることがあります。
そのため、この機能を停止したい場合は、「{プロジェクトのルート}/features/support/app_life_cycle_hooks.rb」の下記の箇所をコメントアウトしてみてください。
After do |scenario| if scenario.failed? # screenshot_embed ←テスト失敗時に、スクリーンショットを自動撮影しないようにします。 end shutdown_test_server end
・機能の限界と拡張
一方でこのCalabash-Androidのスクリーンショット撮影機能には、次のような問題もあります。これらを解決するためには、スクリーンショットの撮影機能を拡張する必要があります。
これを解決するための「ステップ定義」の例を紹介します。
下記の例は、「{プロジェクトのルート}/report/bdd/{フィーチャー名}」ディレクトリを作成し、そこに「{シナリオ名}-x.png」(「x」の部分は0からインクリメントされます)の名前でスクリーンショットを撮影します。
この例をベースに、皆さんのプロダクトに合った出力方法を模索してみてください。
AfterConfiguration do |config| FeatureNameMemory.feature_name = nil FeatureNameMemory.scenario = nil ←追加 end Before do |scenario| (中略) FeatureNameMemory.feature_name = feature_name FeatureNameMemory.scenario = scenario ←追加 (中略) FeatureNameMemory = Class.new class << FeatureNameMemory @feature_name = nil @scenario = nil ←追加 attr_accessor :feature_name, :scenario, :invocation ←追加 end
@@baseDir = "./report/bdd/" Then(/^take photo$/) do screenshotDir = @@baseDir + FeatureNameMemory.feature_name screenshotName = FeatureNameMemory.scenario.name FileUtils.mkdir_p(screenshotDir) unless FileTest.exists?(screenshotDir) screenshot_embed({:prefix => screenshotDir, :name => screenshotName, :label => screenshotName}) end
なお、「FeatureNameMemory.scenario」の仕様については、Cucumber::Ast::Scenarioをご確認ください。
Calabash-AndroidもSeleniumなどと同様、表示に時間がかかるなどして、指定したUIコンポーネントの表示が終わりきっていない状況でステップを実行すると、当該UIコンポーネントが見つからないというエラーとして扱われてしまいます。
こうしたエラーを防止するため、Calabash-Androidでは、ステップの実行タイミングを調整するための「ステップ定義」が用意されています。
・待ち時間を明示的に指定する方法
効果 | テストシナリオ内での実際の記述方法 | ステップ定義 |
---|---|---|
次のステップを実行するまで1秒待つ | Then I wait for 1 second | Then /^I wait for 1 second$/ |
次のステップを実行するまで1秒待つ | Then I wait for a second | Then /^I wait for a second$/ |
次のステップを実行するまで2秒待つ | Then I wait | Then /^I wait$/ |
次のステップを実行するまで、指定した秒数待つ | Then I wait for 3 seconds | Then /^I wait for (\d+) seconds$/ |
・UIコンポーネントの表示を待つ方法
上記「待ち時間を明示的に指定する方法」は、一見便利ではありますが、一方で次のような課題もあります。
「Specification by Example」の11章でも、「待ち時間を明示的に指定する方法は可能ならば避けるべし」と明言されています。そのため、UIコンポーネントの表示を待つ下記の方法の採用をオススメします。
効果 | テストシナリオ内での実際の記述方法 | ステップ定義 |
---|---|---|
プログレスバーが表示されなくなるまで待つ | Given I wait for progress | Then /^I wait for progress$/ |
指定したテキストが表示されるまで待つ | When I wait for "まどか" to appear | Then /^I wait for "([^\"]*)" to appear$/ |
指定したテキストが表示されるまで待つ | Then I wait to see "まどか" | Then /^I wait to see "([^\"]*)"$/ |
指定したテキストが表示されるまで、指定した秒数待つ。指定した秒数を超えるとタイムアウトエラー | Then I wait up to 3 seconds for "まどか" to appear | Then /^I wait up to (\d+) seconds for "([^\"]*)" to appear$/ |
指定したテキストが表示されるまで、指定した秒数待つ。指定した秒数を超えるとタイムアウトエラー | Then I wait up to 3 seconds to see "まどか" | Then /^I wait up to (\d+) seconds to see "([^\"]*)"$/ |
指定したIDのButtonが表示されるまで待つ(Button以外は不可) | Then I wait for the "name" button to appear | Then /^I wait for the "([^\"]*)" button to appear$/ |
指定したアクティビティ名の画面が表示されるまで待つ | Then I wait for the "preview" screen to appear | Then /^I wait for the "([^\"]*)" screen to appear$/ |
指定したIDのViewが表示されるまで待つ | Then I wait for the view with id "add" to appear | Then /^I wait for the view with id "([^\"]*)" to appear$/ |
指定したアクティビティ名の画面が表示されるまで待つ。指定した秒数を超えるとタイムアウトエラー | Then I wait up to 5 seconds for the "preview" screen to appear | Then /^I wait up to (\d+) seconds for the "([^\"]*)" screen to appear$/ |
指定したアクティビティ名の画面が表示されるまで待つ。指定した秒数を超えるとタイムアウトエラー | Then I wait upto 5 seconds for the "preview" screen to appear | Then /^I wait upto (\d+) seconds for the "([^\"]*)" screen to appear$/ |
「データ駆動型テスト」(「データドリブンテスト」「Data-driven testing」とも呼称)とは、Excelなどの表に用意したデータを使用して、同じテストを異なるデータを利用しながら実施すること、またはその仕組みです。
Calabash-Androidでも、前回の『例をベースに仕様を見つける』の表形式と似た方法で、「データ駆動型テスト」を実施できます。
ポイントは、次の通りです。
「{プロジェクトのルート}/features/PreviewCustomer.feature」をベースに、「SpecifyByExampleTable.feature」の表データを組み合わせた例「ScenarioOutlineExample.feature」を、下記に示します。
(中略) Scenario Outline: Add customer information and preview it by using WebView Given I press "button_add" When I enter text "<name>" into field with id "name" ←一番下にある表形式の該当データを取得し、当該「ステップ定義」を呼び出す。 And I enter text "<email>" into field with id "email" And I press "<gender>" And choose age as <age> And go preview And wait for preview screen Then I should see name as "<name>" And I should see "<email>" at "mail" And I should see "<previewGender>" at "gender" And I should see "<age>" at "age" And I should see "<division>" at "division" Examples: ←この宣言の後に、表形式でデータを定義する |name |email |gender |age|previewGender|division| |暁美 ほむら|homura.akemi@example.com |genderFemale|20 |女性 |F1層 | |鹿目 まどか|madoka.kaname@example.com|genderFemale|34 |女性 |F1層 | (以下略)
9行目の指定方法については、『NumberPickerの操作』で解説しています。
今回まで4回にわたり、Calabashの基本からCalabash-Androidをより高度に利用する際に必要となる点について説明してきましたが、いかがでしたでしょうか。
次回は、「Selenium」でモバイルアプリのテストができるツール「Appium」を紹介します。
楽天株式会社 開発プロセスオプティマイゼーション部 品質保証課 テスト駆動開発グループ所属 アジャイルコーチ(執筆当時)
アジャイルコーチおよびシステムアーキテクトとして、実際に開発現場に入り、CI/CD(Jenkins)、TDD/BDDをベースとした技術基盤の構築と、それらをベースとした開発プロセスの改善支援を行っている。モットーは、開発効率の向上による「Be happy!」の実現。
2014年3月より、テスト自動化研究会(STAR)に参加。
2014年7月、アメリカで開催された世界最大のアジャイルのカンファレンス「Agile 2014」に登壇。
著書『プログラミングの教科書 かんたん UML入門』(共著/技術評論社)
ブログ「THE HIRO Says」
Twitter:@hageyahhoo
Copyright © ITmedia, Inc. All Rights Reserved.