Calabash-Androidのテスト高速化、GPS、スクショ、データ駆動型テスト:スマホ向け無料システムテスト自動化ツール(7)(1/2 ページ)
本連載では、AndroidおよびiOSアプリ開発における、システムテストを自動化するツールを紹介していきます。今回は、Calabash-Androidによるテスト実行サイクル高速化の実現や、GPSの操作・スクリーンショットの撮影・ステップの実行タイミングの調整などさまざまな「ステップ定義」、「データ駆動型テスト」を実現するための「Scenario Outline」について解説します。
本連載では、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}」コマンド)実行時に、テストシナリオごとに次の処理が順番に行われます。
- テストサーバーの起動&初期設定の実施
- テスト対象アプリの実機/エミュレーターへのインストール
- テストシナリオの実行
- テスト対象アプリの実機/エミュレーターからのアンインストール
- テストサーバーの停止
これは、テストの冪等性を実現するという観点では、理にかなった方法の一つです。しかし一方で、この一連のテストサーバーの起動〜停止のオペレーションは、非常に時間がかかります。
例えば、本連載の説明で使用しているサンプルプログラムでも、著者の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を実際に半年以上業務で使用してきた経験から、実際のプロダクト開発でどう対応すべきかについて、筆者なりにアドバイスをさせていただきます。
上記の中でも特に「テスト対象アプリの自動アンインストール/インストール設定の解除」については、すぐにフィードバックサイクルのボトルネックとなりがちです。そのため、この設定解除はプロダクト開発の初期に実施することをオススメします。
一方でテストサーバーの自動起動・停止設定については、以下の理由から、初期状態のまま設定を変更しないことをオススメします。
- テストサーバーの自動起動・停止設定を解除した場合、アプリを初期画面へ戻す処理を後処理として独自に用意する必要がある
- テストサーバーの自動起動・停止自体に、アプリを初期画面へ戻してくれる作用がある
- テスト対象アプリの自動アンインストール/インストールと比較すると、実行時間が非常に短いことから対応するROIが低い
上記の全て/一部を採用する場合、手動実行だとミスオペレーションの機会が増え非効率にもなりますので、スクリプト化してCIサーバーなどから呼び出せるようにしておくことをオススメします。
コラム「リリース用に署名されたアプリのテスト実行をスクリプト化する際のコツ」
リリース用に署名されたアプリについて「calabash-android run {YOUR_APK_FILE}」コマンドおよび「calabash-android console {YOUR_APK_FILE}」コマンドを実行する場合、初回のみkeystoreのパスワードの入力を求められます。
CIサーバーなどからの呼び出しを想定してこれらのコマンド実行をshellなどでスクリプト化する際、このkeystoreのパスワードの指定方法が分からず詰まってしまうことが多いです。
この対処方法の1つとして、次のようにリダイレクトを使う方法があります。
- keystoreのパスワードだけを書いたファイルをあらかじめ用意しておく
- 「calabash-android console {YOUR_APK_FILE} < $1」のように、スクリプトの引数としてこのファイル名を渡す
他にも方法はあると思いますが、もし同じ問題につまづいた場合は、まずはこの方法を試してみてください。
Copyright © ITmedia, Inc. All Rights Reserved.
関連記事
- テスト自動化の歴史と今後、良い/悪い事例〜システムテスト自動化カンファレンス2013レポート
テスト自動化を開発の“武器”にするための3つのポイントや、“自動化”の良い事例、悪い事例など、テストの現場を「進化させる」知見が多数紹介されたカンファンレンスの模様をレポートする。 - ビジネス目標を見据えたテスト設計が肝!「DevOps時代のテスト自動化カンファレンス 冬の陣」開催
DevOpsの実践で肝となるソフトウェアテストの自動化。しかし@ITの読者調査でも50%以上が「テスト環境に課題あり」と回答した。これにどう対応すれは良いのだろうか? カンファレンス登壇者の言葉にヒントを探る。 - Kiwi+CocoaPodsで始めるiOSアプリの振る舞いテスト入門
現代の開発現場において欠かせないCI/継続的デリバリを、iOSアプリ開発に適用するためのツールやノウハウを解説する連載。今回は、iOSアプリの機能の振る舞いをテストするテスティングフレームワークの特長とインストールの仕方、主な使い方を解説します。 - Android SDKでビジネスロジックのテストを自動化するには
- 第2回Androidテスト祭りレポート:Android開発の上層テストで失敗しないためのポイントとは
セキュリティ設計や受け入れテストガイドライン、CIツールJenkins+コードレビューGeritt、テスト効率化ノウハウ、リモートテストサービスなど