2014年11月24日月曜日

RobolectricでActivityのテストをやってみる

このエントリーをはてなブックマークに追加 はてなブックマーク - RobolectricでActivityのテストをやってみる

RobolectricでどのようなActivityのテストが出来るか確認してみたのでメモ。

Github

作ってみたプロジェクトはGithubに置きました。

toshihirock/RobolectricSample

Androidアプリ側の実装について本記事には書いていないので実際のコードをご確認いただければ幸いです。

出来ること

  • Activityのライフサイクル(onCreate,onResumeなど)が呼ばれた際の挙動
  • ある操作においてどのようなIntentが投げられているかの確認(他のActivityを呼ぶ側)
  • 特定のIntentが投げられた場合のAcitvityの挙動の確認(他のActivityから呼ばれる側)

出来ないこと

  • 本当に画面遷移をしているかの確認

単体テストなので、当たり前ですが、画面遷移が本当にできているかの確認は出来ません。しかし、「特定の操作でIntentが正しく設定されること(Aボタンが押下された時にhogeというIntentを設定すること)」、「特定のIntentが投げされた時にhogeとなること」はそれぞれ確認できるので、画面遷移に近い確認はできると思います。

Activityのライフサイクル

テストでActivityのライフサイクルを変更できるので、ライフサイクルが変わった時に発生するはずの処理が正しく動作しているか確認できます。

Activity activity = Robolectric.buildActivity(HogeActivity.class).create().get();

以上の記述でonCreateが呼ばれます。 また、以下のようにすることでonResumeを発生させることもできます。

Activity activity = Robolectric.buildActivity(SubActivity.class).create().start().resume().pause().get();

例えばonPauseになった時にあるTextViewの内容が「onPause」になるコードがあった場合には以下のようにテストを書くことができます。

@Test
public void onPauseメソッドが呼ばれたタイミングでTextViewが変更できていること() throws Exception {
    Activity activity = Robolectric.buildActivity(SubActivity.class).create().start().resume().pause().get();

    TextView text = (TextView) activity.findViewById(R.id.textview);
    String actual = text.getText().toString();
    assertThat(actual, is("onPause"));
}

ある操作においてどのようなIntentが投げられているかの確認(他のActivityを呼ぶ側)

あるボタンを押下した時にIntentにputExtraが正しく設定されているかは以下のように確認できます。

@Test
public void ボタン押下時にmessageというIntentでFromDeckardActivityと設定されている事() throws Exception {
    Activity activity = Robolectric.buildActivity(DeckardActivity.class).create().get();

    // click button
    activity.findViewById(R.id.button).performClick();
    ShadowActivity shadowActivity = Robolectric.shadowOf(activity);
    Intent intent = shadowActivity.peekNextStartedActivity();

    String actual = intent.getStringExtra("message");
    assertThat(actual, is("FromDeckardActivity"));
}

peekNextStartedActivityメソッドで起動した(はず)のIntentを取得できるので、そのIntentを確認することで設定が合っているか確認できます。また、peekNextStartedServiceメソッド及びpeekNextStartedActivityForResultメソッドを利用することでサービスの起動やStartActivityForResultを使って起動する際の挙動確認もできます。

なお、Intentに設定したクラス名の確認は以下のようにすることで可能です。

@Test
public void ボタン押下時にIntentにSubActivityクラスが設定されている事() throws Exception {
    Activity activity = Robolectric.buildActivity(DeckardActivity.class).create().get();

    // click button
    activity.findViewById(R.id.button).performClick();
    ShadowActivity shadowActivity = Robolectric.shadowOf(activity);
    Intent intent = shadowActivity.peekNextStartedActivity();

    ShadowIntent shadowIntent = Robolectric.shadowOf(intent);
    String actualClassName = shadowIntent.getComponent().getClassName();
    assertThat(actualClassName, is(SubActivity.class.getName()));
}

特定のIntentが投げられた場合のAcitvityの挙動の確認(他のActivityから呼ばれる側)

呼ばれる側のActivityも挙動を確認できます。

@Test
public void messageというIntentが設定された場合にTextviewに内容を表示すること() throws Exception {
    Intent intent = new Intent();
    intent.putExtra("message", "FromDeckardActivity");

    Activity activity = Robolectric.buildActivity(SubActivity.class).withIntent(intent).create().get();

    TextView text = (TextView) activity.findViewById(R.id.textview);
    String actual = text.getText().toString();
    assertThat(actual, is("FromDeckardActivity"));
}

@Test
public void messageというIntentが設定されていない場合にTextViewに設定されていない旨が表示されること() throws Exception {
    Activity activity = Robolectric.buildActivity(SubActivity.class).create().visible().get();

    TextView text = (TextView) activity.findViewById(R.id.textview);
    String actual = text.getText().toString();
    assertThat(actual, is("not found message extra"));
}

設定されるはずのIntentを作成し、withIntentメソッドを利用することで挙動の確認ができます。

参考

画面遷移をrobolectricでテストする

Driving the Activity Lifecycle

0 件のコメント:

コメントを投稿