Androidでのテストで色々悩んだ結果robotiumになった件

  • 46
    Like
  • 1
    Comment
More than 1 year has passed since last update.

Robolectric-FINAL.png20110601224550-1.jpg

鹿だよ。
Androidの自動化テストで以下のフレームワークを試してみました。そのレポです。

  • Espresso 1.1
  • Robolectric 2.3
  • robotium 5.2.1

結果

いきなり結果ですが、老舗のRobotiumを選びました。残りの2つは不安定だったり、よくわかんなかったりで諦めました。

Espresso

Google I/O 2013 で発表されてたので、最近のトレンドは Espresso なのかなーと思って最初に手を出しました。
よく見たらコミットが今年の1月で止まってる・・・。これはもう破棄されてるね・・・。
Changes - android-test-kit - Google's Testing Tools For Android - Google Project Hosting

使えなかったところ

Activityを跨いだ画面遷移のテストの結果がすごく不安定だった。OKだったりNGだったり。

public void testSayHello() {
  //このclickで画面遷移すると仮定する。
  onView(withId(R.id.greet_button))
    .perform(click());

  //遷移後の画面に"Hello Steve!"が表示されるが、このassertはOKだったりNGだったりする。
  onView(withText("Hello Steve!"))
    .check(matches(isDisplayed()));
}

Robolectric

こっちは頻繁に更新されてるし、googleの検索結果も多いので安心感があります。

使えなかったところ

基本的に Robolectric はgradleから使えない(または使いにくい)。でも、robolectricのチームがgradleのpluginを作ってくれてて、使いやすくなってる。
robolectric/robolectric-gradle-plugin

ここまではいいのだけど、ちょいちょいバグがあって、なかなか動かすところまで行かない。動くようになっても、小難しいテストをやろうとするとノウハウが見つからないことが多い。

applicationIdSuffix バグ

gradleを使ってるなら

buildTypes {
  debug{
    applicationIdSuffix ".debug"
  }
}

とかして、debug用のパッケージを作ってたりすると思うけど、これが起因のバグがあって動かすことができなかった。

リソースが見つからない

上記の状態で実行すると

NotFoundException: no such label string/app_label

となってしまう。ちゃん app/build/intermediates/res/debug/values にあるのに。うーん。。。

マルチスレッドのテストができない

マルチスレッドの同期がどうしてもできなかった。

    //クリックすると非同期処理が始まる
    clickOn(view);

    //ちょっとまってくれる(願望)
    Robolectric.runUiThreadTasksIncludingDelayedTasks() 

    //非同期処理終了後、ダイアログが表示されるはずなので取得する。
    AlertDialog alert = ShadowAlertDialog.getLatestAlertDialog();

    //だが、この時点でalertはnull
    assertNotNull(alert);

たぶん、もうちょっと勉強したら動くような気がするけど、時間は永遠ではないのでしばらく放置することに。

robotium

Android界隈では老舗のテストフレームワーク。アップデートも定期的に行われてる。
説明書きが何故かpdfという、ちょっとクレイジーな運用方針だ。

良かったところ

画面遷移テストは安定してて、非同期テストもちゃんと動く。記法はEspressoより書きにくいけど、ActivityInstrumentationTestCase2 より書きやすくなっている。コード量は今回挙げたフレームワークの中で一番少なくなりそう。

画面遷移のテスト

わずか2行でできた。やばい。

public void testTerm(){
    //viewのクリック処理
    solo.clickOnView(mActivity.findViewById(R.id.termView));
    //新規に開いたActivityと一致するか
    solo.assertCurrentActivity("利用規約画面", TermWebActivity_.class);
}

というわけで、Robotiumでがんばります。