はじめに
環境準備編 の続きです。
Calabash(が利用している Cucumber)は自然言語でテストを記述できるという特徴があります。テストの各ステップを日本語で書けるように準備をします。
bundle exec は省略します。Bundler 使って Calabash をインストールした場合は、
cucumber
は
bundle exec cucumber
と置き換えてください。
各ファイルの役割と用語解説
calabash-ios gen で生成された雛形の構成は以下のようになっています。
features
├── sample.feature
├── steps
│ └── sample_steps.rb
└── support
├── 01_launch.rb
├── dry_run.rb
├── env.rb
└── patches
└── cucumber.rb
拡張子が feature のファイルにフィーチャ(機能)を記述します。これが一番大きな単位です。1ファイルには1フィーチャしか記述できません。
feature ファイルの書き方は Cucumber のフィーチャの文法 - Gherkin が参考になります。
フィーチャの中に幾つかのシナリオを書きます。シナリオは複数あって構いません。正常系とか異常系とか。各シナリオはステップの羅列でできています。
以下は雛形として出力された sample.feature の中身です。
Feature: Sample Feature
Scenario: Sample Scenario
Given the app has launched
And I have done a specific thing
When I do something
Then something should happen
steps の中にはステップに書くコマンドを書いておきます。これを日本語で用意しておけば、ステップを日本語で記述できます。
以下が雛形として出力された sample_steps.rb の中身(コメントは省略)です。これは Ruby で記述されています。
Given(/^the app has launched$/) do
wait_for do
!query("*").empty?
end
end
And(/^I have done a specific thing$/) do
did_something = true
unless did_something
fail 'Expected to have done something'
end
end
When(/^I do something$/) do
end
Then(/^something should happen$/) do
end
正規表現を使って、自然言語で書かれたステップ記述を Calabash が用意している API 呼び出しに変換します。ここに日本語でコマンドを用意していけば、日本語でステップを記述できるようになります。
support はいじらないので割愛。
フィーチャファイルを日本語で書けるようにする
最初から日本語で書けます。以下を実行してみてください。
cucumber --i18n ja
英語に対応する日本語が表示されます。
| feature | "フィーチャ", "機能" |
| background | "背景" |
| scenario | "シナリオ" |
| scenario_outline | "シナリオアウトライン", "シナリオテンプレート", "テンプレ", "シナリオテンプレ" |
| examples | "例", "サンプル" |
| given | "* ", "前提" |
| when | "* ", "もし" |
| then | "* ", "ならば" |
| and | "* ", "かつ" |
| but | "* ", "しかし", "但し", "ただし" |
| given (code) | "前提" |
| when (code) | "もし" |
| then (code) | "ならば" |
| and (code) | "かつ" |
| but (code) | "しかし", "但し", "ただし" |
日本語で書くには、feature ファイルの先頭に日本語を指定する行を書くだけです。雛形を日本語化してみましょう。
# language: ja
フィーチャ: サンプルフィーチャ
シナリオ: サンプルシナリオ
前提 the app has launched
かつ I have done a specific thing
もし I do something
ならば something should happen
シナリオの各ステップはまだ日本語では書けません。ちなみに「前提」とか「かつ」とか「もし1」とか頭に付いてますが、何を書いても動作は一緒です。以下のように書いても同じ順番でステップが実行されます。
# language: ja
フィーチャ: サンプルフィーチャ
シナリオ: サンプルシナリオ
* the app has launched
* I have done a specific thing
* I do something
* something should happen
ステップを日本語で書けるようにする
ここが本命です。英語版は Calabash 側で汎用的に使えるもの を用意してくれています。プロジェクトの features/steps の下に置くのはプロジェクト専用のものを追加する場所です。
でも日本語版は用意されていません。なので Calabash 側に用意されている汎用のものを参考にして日本語版を作成し、それをプロジェクト用の場所に calabash_japanese_steps.rb として置くことにします。
各ステップ定義は自然言語で書ける関数と見なせます。以下のように正規表現で記述し、() にマッチした部分を引数として扱います。引数として扱わないものは (?:press|touch) のように ?: を付けます。正規表現の書き方は Ruby リファレンスマニュアル - 正規表現 を参考にしてください。
Then /^I (?:press|touch) on screen (\d+) from the left and (\d+) from the top$/ do |x, y|
touch(nil, { offset: { x: x.to_i, y: y.to_i } })
sleep(STEP_PAUSE)
end
ちなみにここでも Given, Then などはどれを選んでも同じです。Given で定義したら Given でしか使えないとか、そういうことはありません。
macro を使ってステップ定義の中で他のステップを呼び出すこともできるので、日本語ステップ定義から英語ステップを呼び出すという方法が取れます。こんな感じですね。
Then /^画面の\((\d+), *(\d+)\)座標を(?:タッチ|タップ)する$/ do |x, y|
macro "I touch on screen #{x} from the left and #{y} from the top"
end
Ruby 知らない人のために説明しておくと、ダブルクォーテーション文字列の中には #{x} のようにして変数の値を埋め込めます。またパーセント記法というのを使うと、ダブルクォーテーション自体を含む文字列でダブルクォーテーションのエスケーブが必要なくなります。
Then /^"([^\"]*)"を(?:押す|タッチする|タップする)$/ do |name|
# % の後の文字は自由に選べるので、文字列が含まない文字にする。
macro %(I touch "#{name}")
end
しかしここでは英語版を呼び出すことはせず、以下のように定義の中身を英語版と同じにしました(その方が楽)2。
Then /^画面の\((\d+), *(\d+)\)座標を(?:タッチ|タップ)する$/ do |x, y|
touch(nil, { offset: { x: x.to_i, y: y.to_i } })
sleep(STEP_PAUSE)
end
Then /^"([^\"]*)"を(?:押す|タッチする|タップする)$/ do |name|
touch("view marked: '#{name}'")
sleep(STEP_PAUSE)
end
日本語化したものは長いので Gist に置いておきました。動作確認できていないものが沢山なので、多分(特に正規表現部分に)バグが一杯あります。
まとめ
Calabash のテストを日本語で書けるようにしました。後はバリバリテストを書いて・・・といきたいところですが、まだ
- 本当に WKWebView を扱えるのか?
- 日本語の文字入力は大丈夫か?
- ビュー階層を見るにはどうするのか?
- ビュー階層の中から要素を指定するにはどうするのか?
- テストシナリオ実行前にアプリを再インストールすることは可能か?
などなど確認したいことがあります。次の記事ではそれらについて色々試してみます。