2015年11月27日金曜日

[Capybara] [Turnip] 複数のエディションのテストで分岐がある場合の対応方法

Capybara + Turnipを使ってE2E(End-to-End)テストをする時に、テスト対象のサービスや製品に複数のエディションがあり、画面遷移は殆ど共通なのですが、あるエディションにだけに他のエディションにはない画面(遷移)がある場合のノウハウ。

まぁ、愚直にやるなら、各エディション分featureファイルを作れば良いのですが、DRYじゃないし、タイピングも怠いです。RSpecからテストを実行する時にパラメータを与えて分岐できたら幸せじゃないだろうか?とも考えたのですが、そのような方法は私は見つけられず、パラメータを覚えておかなければいけないのも考えてみると怠いです。

というわけで、featureファイルに全部テストデータを突っ込みつつ、分岐もすれば比較的怠くなくいけた感がありましたので方法を書いておきます。

まずは、サンプル。

やっていることは至ってシンプルです。Capybara + Turnipでは<>でシナリオ内に変数を埋め込むことができます(例で言うと<DDDする>が変数です)。この変数にfeatureファイルの最下部に記載した「例:」の各値を当てはめて逐次実行することをCapybara + Turnipは行ってくれます。例では、5行の定義がありますが、最初の一行はヘッダで変数名と同じにする必要があります。残り4行がデータになり、Capybara + Turnipは各行から値を取り出しては変数にその値を代入し、代入した結果と一致するstepを実行します。

例では上から順に「何もしない」、「何もしない」、「DDDする」、「何もしない」と定義していますので、1番目、2番目、4番目は<DDDする>というstepが"何もしない"になります。そして、3番目だけが、"DDDする"というstepになります。

stepsファイルを見ると、二つのstepだけ定義しています。"何もしない"と"DDDする"の二つです(もちろん略しているだけで、他にも"AAAする"、"BBBする"などが定義されていなければいけません)。step "何もしない"は見てのとおり何もしません。step "DDDする"は何か仕事をしています。

この様に、ステップ名全体を変数化し、"何もしない"といった様な何の処理もしない空のstepを用意することで、一部のエディションにだけ存在する画面に分岐してテストすることが一つのfeatureファイルで可能になります。殆どが同じ処理のシナリオをfeatureを分けるなどをして書く必要はないですし、テストデータ(例:の表組のデータのことです)もfeatureファイルに閉じ込めておくことができます(外部から入力を与える必要がない)。

ちなみに、例:の表組を使うためには、featureファイルにて「シナリオ」ではなく、「シナリオアウトライン」を使う必要があることに注意してください。

2015年11月7日土曜日

[Capybara] [RSpec] [Poltergeist] [Turnip] E2Eテストを自動化する手順

WebシステムのE2E(End-to-End)テストの自動化を、Capybara + RSpec + Poltergeist + Turnipで行ってみました。新規に自動化のスクリプトを作っていく手順を備忘で書いておきます。環境はMacOSX EI Capitanです。

Gemfileを次の内容に更新します。

そして、bundle installを実行します。
次に、RSpecとTurnipの設定ファイルを用意します。

spec/turnip_helper.rbを作ります。

ここまででテストシナリオを作成する環境の準備が整います。

では、テストシナリオを書いていきます。
Turnipで日本語が使えるようになっていますので、日本語で書いていきます。
簡単な例として、Googleにアクセスして、キーワードTurnipで検索し、その結果をsnapshotに取るというシナリオを作ってみます。

シナリオはfeatureファイルに記述します。
spec/features/google_search.featureを次の内容で作りました。

シナリオに呼応するstepファイルを記述します。ファイルの命名規則に注意してください。spec/turnip_helper.rbのDir.glob()で指定したパスにマッチするように作ります。
spec/steps/google_search_steps.rb

テストが出来上がったので実行します。実行前にスナップショットを保存するディレクトリを mkdir snapshot で作っておきます。

無事にテストが通れば次のようになります。
スナップショットも作成されています。

2015年11月4日水曜日

[Android] Recent Apps(アプリ履歴)にActivityを表示させない方法

非常にニッチなニーズなのですが、諸般の事情で実装する必要があったので備忘で書いておきます。

Recent Apps(アプリ履歴、タスク一覧ともいうのかな?)に対象のActivityを非表示にするには、対象Activityがフォアグラウンドになければ


にある通り、AndroidManifest.xmlにて対象Activityの<activity>に

android:excludeFromRecents="true"

を指定してあげれば非表示になります。

問題は、対象Activityがフォアグラウンドにある場合で、その場合は、下記のようにexcludeFromRecents以外に色々と設定してあげる必要があります。
(TargetActivityはご自身のActivity名に読み変えてください)。


正直、各設定の詳細な意味は深く理解していません(汗
おまじないに近いです。

次の記事を参考にしました。

Issue 53313 - android - Foreground service killed when receiving broadcast after acitivty swiped away in task list - Android Open Source Project - Issue Tracker - Google Project Hosting

2015/11/7追記:

もっと簡単で確実な方法がありました。onPause()でsetTheme(android.R.style.Theme_NoDisplay)すれば良いです。

protected void onPause() {
    setTheme(android.R.style.Theme_NoDisplay);
    super.onPause();
}