本連載では、AndroidおよびiOSアプリ開発における、システムテストを自動化するツールを紹介していきます。今回は、Calabash-AndroidによるBDD実践のポイント、表形式の活用による仕様の発見、「Living documentation」で「見せる化」を実現する方法などについて解説します。
本連載では、AndroidおよびiOSアプリ開発における、システムテストを自動化するツールを紹介していきます。前々回の「iOS/AndroidにCucumberのBDDをもたらすテストフレームワークCalabashの基礎知識とインストール」から数回にわたり「Calabash」、特に「Calabash-Android」を中心に解説しています。
前回の「Calabash-Androidでテストシナリオを作成する方法」では、Calabash-Androidで事前に用意されている「ステップ定義」を使用してテストシナリオを作成する方法を解説。Calabash-Androidのテストで必要になる、各種UIコンポーネントの特定・操作・検証方法を紹介し、ステップ定義の仕方やUIコンポーネントを調査する「console」について解説しました。
今回は、Calabash-AndroidによるBDDの実践を中心に、「Living documentation」で「見せる化」を実現するためにJenkinsプラグインを活用する方法や、タグによるテスト実行対象の特定方法などを解説します。
Calabash-Androidは、BDD(Behavior-Driven Development/振る舞い駆動開発)をAndroidで実現するためのツールです。
BDDの理論面については、連載「いまさら聞けないTDD/BDD超入門」が非常に詳しいので、そちらに譲るとして、本稿ではCalabash-AndroidでBDDを実践するためのポイントを紹介します。
前回まで説明してきた通り、Calabash-Androidは、Gherkinによる「フィーチャー」「シナリオ」「ステップ」の形式でテストケース(シナリオ)を記述できます。
これらは、開発者やテスターだけではなく、ビジネスアナリストやUXデザイナーらの「ビジネスステークホルダー」たちにも読みやすく記述できます。また、これらは実際にAndroidの実機/エミュレーターで動作させることができます。
つまり、Calabash-Androidではテストが、次の2つの側面を持っているといえます。
このBDDが併せ持つ2つの側面を、「実行可能な仕様」(Executable Specification)と呼称します。
「実行可能な仕様」は、実際に動作させて確認できます。
この動作確認によるフィードバックにより、さらに作るべきプロダクトの仕様が詳細になります。また、このことはプロダクト開発に関わる全ロールメンバー、ステークホルダー間で、開発/テスト/提供すべきモノに対する共通認識を作りやすくなるというメリットがあります。
ソフトウエア開発では、「ロールやステークホルダーごとにサイロ化が生じて、お互いのコミュニケーションが阻害されることで、プロジェクトの失敗を招いている」という話が少なくありません。
このサイロ化を避けプロダクトの共通認識を作り開発、運用を成功させるために、お互い共通のコミュニケーションツールとして、このCalabash-Androidのテストケース(シナリオ)を活用してみましょう。
「実行可能な仕様」で、プロダクトを作れるチームを、そしてプロダクトを作るのです。
BDDの実践者たちは、テストケース(シナリオ)でプロダクトの動作例を書いてステークホルダーたちと会話しながら、そのプロダクトの仕様を見つけていくというスタイルを採ることが多いです。
このアプローチを、「Specification by Example」と呼称します。「例をベースに、仕様を見つけていく」という意味です。
ビジネスステークホルダーらと対話しながら、システムの挙動例を書き出し、仕様の詳細を確認、確定していく。そして、その対話の結果自体がテストケース(シナリオ)にもなる。これは、上述の『「実行可能な仕様」で作る』より具体的、実践的な内容になります。
以下では、具体的、実践的な例として、Calabash-Androidの表形式を活用して「例をベースに仕様を見つける」方法を紹介します。
まず実際に「例をベースに仕様を見つける」前に、Calabash-Androidで表形式の「ステップ定義」を作成する方法を説明します。
ここでは、「{プロジェクトのルート}/features/PreviewCustomer.feature」をコピーして作成した「SpecifyByExampleTable.feature」を例に説明します。
「PreviewCustomer.feature」のオリジナルステップをベースに、Customer Detail画面のデータ入力部分、およびCustomerPreviewActivity画面で値を検証する部分とを表形式で指定するステップを、下記のように定義します。
When I enter customer information and preview it as follows: |name |email |gender|age|previewGender|division| |暁美 ほむら|homura.akemi@example.com |female|20 |女性 |F1層 | |鹿目 まどか|madoka.kaname@example.com|female|34 |女性 |F1層 |
ポイントは次の通りです。
この例では、1行目をデータ項目として扱っていますが、この表の作り方は自由です。扱い方は、次の「ステップ定義」ファイルで調整します。
今回の例では、前回の「{プロジェクトのルート}/features/step_definitions/PreviewCustomer_steps.rb」に下記を追加します。
When(/^I enter customer information and preview it as follows:$/) do |table|
ポイントは次の通りです。
以下が具体的な実装例です。
When(/^I enter customer information and preview it as follows:$/) do |table| table.hashes().each do |raw_data| # Input on Customer Detail enterText("name", raw_data["name"]) enterText("email", raw_data["email"]) chooseRadioButton(raw_data["gender"]) unless raw_data["age"].empty? changeAgePicker(raw_data["age"]) end # Execute SUT touchButtonPreview waitForPreviewScreen # Validate on Preview validateNameOnWebView(raw_data["name"]) validateWebViewItem(raw_data["email"], "mail") validateWebViewItem(raw_data["previewGender"], "gender") unless raw_data["age"].empty? validateWebViewItem(raw_data["age"], "age") else validateWebViewItem("NaN", "age") end validateWebViewItem(raw_data["division"], "division") # Move back to Customer Detail and tear down press_back_button waitForCustomerDetailScreen clearText("name") clearText("email") end end
ちなみに、5、6行目に出てくる「enterText」メソッドは、「PreviewCustomer.feature」にある下記の実際の具体的な実装内容(「{Rubyのインストールディレクトリ}/lib/ruby/gems/{Rubyのバージョン}/gems/calabash-android-0.5.2/lib/calabash-android/steps/enter_text_steps.rb」の「Then /^I enter text "([^\"]*)" into field with id "([^\"]*)"$/ do |text, id|」)を元にしています。
When I enter text "ほむら" into field with id "name"
「enterText」メソッドは、この「ステップ定義」ファイルに下記のように追加したものです。
def enterText(id, text) enter_text("android.widget.EditText id:'#{id}'", text) end
なお、表形式の詳細については、「表(Cucumber::Ast::Table)の仕様」も併せて、ご確認ください。
Copyright © ITmedia, Inc. All Rights Reserved.