Edited at

WKWebViewを使うアプリのUI自動テストにCalabash-iOSを使ってみた(日本語準備編)

More than 3 years have passed since last update.


はじめに

環境準備編 の続きです。

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 を扱えるのか?

  • 日本語の文字入力は大丈夫か?

  • ビュー階層を見るにはどうするのか?

  • ビュー階層の中から要素を指定するにはどうするのか?

  • テストシナリオ実行前にアプリを再インストールすることは可能か?

などなど確認したいことがあります。次の記事ではそれらについて色々試してみます。





  1. 「もし」は条件分岐しそうに思えますが、ifではなくwhenに対応しています。文の先頭にかける単語でwhenに対応する良い日本語が他になかったものと思われます。 



  2. CalabashのバージョンアップでAPIが変わる可能性を考えると、英語版を呼び出すアプローチの方が良いかもしれません。