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

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

本連載では、AndroidおよびiOSアプリ開発における、システムテストを自動化するツールを紹介していきます。今回は、Calabash-Androidによるテスト実行サイクル高速化の実現や、GPSの操作・スクリーンショットの撮影・ステップの実行タイミングの調整などさまざまな「ステップ定義」、「データ駆動型テスト」を実現するための「Scenario Outline」について解説します。

[伊藤宏幸,テスト自動化研究会(STAR),楽天株式会社]
「スマホ向け無料システムテスト自動化ツール」のインデックス

連載目次

 本連載では、AndroidおよびiOSアプリ開発における、システムテストを自動化するツールを紹介していきます。連載第4回の「iOS/AndroidにCucumberのBDDをもたらすテストフレームワークCalabashの基礎知識とインストール」から数回にわたり、「Calabash」、特に「Calabash-Android」を中心に解説しています。

 前々回(連載第5回)の「Calabash-Androidでテストシナリオを作成する方法」では、Calabash-Androidで事前に用意されている「ステップ定義」を使用してテストシナリオを作成する方法を解説。Calabash-Androidのテストで必要になる、各種UIコンポーネントの特定・操作・検証方法を紹介し、ステップ定義の仕方やUIコンポーネントを調査する「console」について解説しました。

 前回(連載第6回)の「Calabash-AndroidによるBDDの実践とJenkinsによる『Living documentation』」では、Calabash-AndroidによるBDDの実践を中心に、「Living documentation」で「見せる化」を実現するためにJenkinsプラグインを活用する方法や、タグによるテスト実行対象の特定方法などを解説しました。

 今回は、これまでの連載(第4〜6回)に関連した、さまざまなテクニックを紹介します。

テストのライフサイクル変更によるテスト実行サイクル高速化の実現

 連載第4回の『コラム「テストのライフサイクル」』でも説明しましたが、Calabash-Androidの初期設定では、テスト(「calabash-android run {YOUR_APK_FILE}」コマンド)実行時に、テストシナリオごとに次の処理が順番に行われます。

  1. テストサーバーの起動&初期設定の実施
  2. テスト対象アプリの実機/エミュレーターへのインストール
  3. テストシナリオの実行
  4. テスト対象アプリの実機/エミュレーターからのアンインストール
  5. テストサーバーの停止

 これは、テストの冪等性を実現するという観点では、理にかなった方法の一つです。しかし一方で、この一連のテストサーバーの起動〜停止のオペレーションは、非常に時間がかかります。

 例えば、本連載の説明で使用しているサンプルプログラムでも、著者のPCでは、テスト対象アプリのアンインストール/インストールだけで1テストシナリオ当たり平均4秒弱かかっています。

 フィーチャー/テストシナリオのまだ少ないプロジェクト初期はさほど気にならないかもしれませんが、フィーチャー/テストシナリオが質・量ともに充実してくるプロジェクト中〜後期では、テストの冪等性の実現以上にオーバーヘッドが掛かり過ぎてしまいます。

 その結果、フィードバックサイクルを長くしてしまう主原因になる恐れがあります(フィードバックサイクルの長期化は、メンバーがテストへのモチベーションを失う主要素の一つなので、注視する必要があります)

 以下では、この一連のテストのライフサイクルを変更することで、テストの実行サイクルの高速化を実現する方法を説明します。

テストサーバーの自動起動・停止設定の解除

 テストサーバーの自動起動・停止の設定は、「{プロジェクトのルート}/features/support/app_life_cycle_hooks.rb」に定義されています。下記の箇所をコメントアウトすることで、シナリオごとのテストサーバーの自動起動・停止設定を解除できます。

Before do |scenario|
#  start_test_server_in_background	←シナリオ開始前に、テストサーバーを起動しないようにします。
end
 
After do |scenario|
  if scenario.failed?
    screenshot_embed
  end
#  shutdown_test_server				←シナリオ終了後に、テストサーバーを停止しないようにします。
end

 一方で上記の設定を行う場合、別途以下の作業を任意のタイミングで実施する必要があります(後述)。

  • テスト開始前に、テストサーバーを手動起動すること
  • テスト終了後に、テストサーバーを手動停止すること

テスト対象アプリの自動アンインストール/インストール設定の解除

 テスト対象アプリの自動アンインストール/インストールの設定は、「{プロジェクトのルート}/features/support/app_installation_hooks.rb」に定義されています(※注)。

 下記の箇所(22〜24行目)をコメントアウトすることで、シナリオごとのテスト対象アプリの自動アンインストール/インストール設定を解除できます。

#uninstall_apps
#install_app(ENV["TEST_APP_PATH"])
#install_app(ENV["APP_PATH"])

 一方で上記の設定を行う場合、別途以下の作業を任意のタイミングで実施する必要があります(後述)。

  • テスト開始前に、テスト対象アプリを手動インストールすること
  • テスト終了後に、テスト対象アプリを手動アンインストールすること

※注

 厳密にはこの処理は、違うシナリオでもフィーチャー名が同じ場合は実行されません。つまり、以下のような場合には、特に上述のコメントアウトをしなくても、テスト対象アプリの自動アンインストール/インストールは実行されないことになります。

  • 1つのフィーチャーファイルのシナリオが順次実行される場合
  • 複数のフィーチャーファイルで、同一のフィーチャー名を使用している場合

 しかし、条件や挙動がトリッキーになることを避ける観点から、上述のコメントアウトをすることをオススメします。


テストの実施方法

 上記の設定を行った上でのテストの実施方法は、以下の通りです。

【1】実機の接続/エミュレーターの起動

【2】テスト対象アプリの実機/エミュレーターへのインストール、およびテストサーバーの起動

 プロジェクトのルートディレクトリで「calabash-android console {YOUR_APK_FILE}」コマンドを実行し、連載第5回で紹介した「console」を起動します。

$ calabash-android console app/build/outputs/apk/app-calabash-release.apk

 consoleで「reinstall_apps」コマンドを実行し、テスト対象アプリを実機/エミュレーターへ再インストール(アンインストール+インストール)します。

irb(main):001:0> reinstall_apps
1968 KB/s (348794 bytes in 0.173s)
1693 KB/s (553402 bytes in 0.319s)
nil

 consoleで「start_test_server_in_background」コマンドを実行し、テストサーバーを起動します。

irb(main):002:0> start_test_server_in_background
WARNING: linker: libdvm.so has text relocations. This is wasting memory and is a security risk. Please fix.
nil

 consoleで「exit」コマンドを実行するか、または「Ctrl」+「C」キーを押し、consoleを停止します。

【3】(任意)過去の不要なテストサーバーの削除

 アプリのビルド/インストール/テストを繰り返した場合、「{プロジェクトのルート}/test_servers」以下には、過去に使用したテストサーバーのapkファイルが累積して残ります。もし、これらがマシンのディスク容量を圧迫するような場合は、下記コマンドなどで過去の不要なテストサーバー/apkファイルを削除してください。

rm -r ./test_servers

【4】テストシナリオの実行

 プロジェクトのルートディレクトリで「calabash-android run {YOUR_APK_FILE}」コマンドを実行します。

$ calabash-android run app/build/outputs/apk/app-calabash-release.apk

 ちなみに、テストサーバーを起動せずに「calabash-android run {YOUR_APK_FILE}」コマンドを実行すると、下記エラーが発生します。

HTTPClient::KeepAliveDisconnected (HTTPClient::KeepAliveDisconnected) (RuntimeError)

【5】テストサーバーの停止

 プロジェクトのルートディレクトリで「calabash-android console {YOUR_APK_FILE}」コマンドを実行し、consoleを起動します。

$ calabash-android console app/build/outputs/apk/app-calabash-release.apk

 consoleで「shutdown_test_server」コマンドを実行し、テストサーバーを停止します。

irb(main):001:0> shutdown_test_server
nil

 consoleで「exit」コマンドを実行するか、または「Ctrl」+「C」キーを押し、consoleを停止します。

実際には、どうするべきか?

 Calabash-Androidを実際に半年以上業務で使用してきた経験から、実際のプロダクト開発でどう対応すべきかについて、筆者なりにアドバイスをさせていただきます。

 上記の中でも特に「テスト対象アプリの自動アンインストール/インストール設定の解除」については、すぐにフィードバックサイクルのボトルネックとなりがちです。そのため、この設定解除はプロダクト開発の初期に実施することをオススメします。

 一方でテストサーバーの自動起動・停止設定については、以下の理由から、初期状態のまま設定を変更しないことをオススメします。

  1. テストサーバーの自動起動・停止設定を解除した場合、アプリを初期画面へ戻す処理を後処理として独自に用意する必要がある
  2. テストサーバーの自動起動・停止自体に、アプリを初期画面へ戻してくれる作用がある
  3. テスト対象アプリの自動アンインストール/インストールと比較すると、実行時間が非常に短いことから対応するROIが低い

 上記の全て/一部を採用する場合、手動実行だとミスオペレーションの機会が増え非効率にもなりますので、スクリプト化してCIサーバーなどから呼び出せるようにしておくことをオススメします。

コラム「リリース用に署名されたアプリのテスト実行をスクリプト化する際のコツ」

 リリース用に署名されたアプリについて「calabash-android run {YOUR_APK_FILE}」コマンドおよび「calabash-android console {YOUR_APK_FILE}」コマンドを実行する場合、初回のみkeystoreのパスワードの入力を求められます。

 CIサーバーなどからの呼び出しを想定してこれらのコマンド実行をshellなどでスクリプト化する際、このkeystoreのパスワードの指定方法が分からず詰まってしまうことが多いです。

 この対処方法の1つとして、次のようにリダイレクトを使う方法があります。

  1. keystoreのパスワードだけを書いたファイルをあらかじめ用意しておく
  2. 「calabash-android console {YOUR_APK_FILE} < $1」のように、スクリプトの引数としてこのファイル名を渡す

 他にも方法はあると思いますが、もし同じ問題につまづいた場合は、まずはこの方法を試してみてください。


       1|2 次のページへ

Copyright© 2017 ITmedia, Inc. All Rights Reserved.

@IT Special

- PR -

TechTargetジャパン

この記事に関連するホワイトペーパー

RSSについて

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

メールマガジン登録

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