連載
» 2015年04月14日 05時00分 公開

スマホ向け無料システムテスト自動化ツール(7):Calabash-Androidのテスト高速化、GPS、スクショ、データ駆動型テスト (2/2)

[伊藤宏幸,テスト自動化研究会(STAR),楽天株式会社]
前のページへ 1|2       

さまざまな「ステップ定義」

 連載第5回では、「ステップ定義」の基本を解説し、NumberPickerを操作するためのステップ定義方法を紹介しましたが、ステップ定義には、他にもさまざまなものがあります。

GPSの操作

 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
{プロジェクトのルート}/features/support/app_life_cycle_hooks.rb

@@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
{プロジェクトのルート}/features/step_definitions/PreviewCustomer_steps.rb

 なお、「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コンポーネントの表示を待つ方法

 上記「待ち時間を明示的に指定する方法」は、一見便利ではありますが、一方で次のような課題もあります。

  • UIコンポーネントの表示時間が、実行するPC/エミュレーター/実機によってそれぞれ異なるため、待ち時間を一律に指定しづらい
    • 待ち時間を一定にするために、テスト対象のエミュレーター/実機を絞ることは、テストの目的として本末転倒
  • テストシナリオ内に待ち時間を指定するステップを増やしすぎると、本来検証したいことが見えづらくなってしまう

 「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$/

「データ駆動型テスト」を実現するための「Scenario Outline」

 「データ駆動型テスト」(「データドリブンテスト」「Data-driven testing」とも呼称)とは、Excelなどの表に用意したデータを使用して、同じテストを異なるデータを利用しながら実施すること、またはその仕組みです。

 Calabash-Androidでも、前回の『例をベースに仕様を見つける』の表形式と似た方法で、「データ駆動型テスト」を実施できます。

 ポイントは、次の通りです。

  • 「Scenario Outline:」で始まるステップを定義する
  • 「データ駆動型テスト」で代入したい箇所は、「<データ名>」の書式でシナリオに記述する
    • ちなみに、「<データ名>」はそのままリテラルとして扱われるため、ダブルクォーテーションを使用する「ステップ定義」を使用する場合は、「"<データ名>"」のようにダブルクォーテーションをステップ内で明示的に指定する
  • シナリオの最後に「Examples:」と書き、代入したいデータ表を定義する

 「{プロジェクトのルート}/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の操作』で解説しています。

次回はSeleniumでモバイルアプリのテストができる「Appium」

 今回まで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


前のページへ 1|2       

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。