IdlingResourceを使ったUIテスト
Espressoを使って,このようなテストを書きました.
- リスト表示用のデータをサーバからとってくる
- データをリストにセットする
- リストをクリックする
- 遷移先の詳細画面に,正しい情報が送れたか確認
このテストでは,
「リストにデータがセットされたのを確認してから,クリック」
という流れを書かなければいけません.
Espressoでは,テストするアクションのタイミングをコントロールできるよう,
IdingResource
というものが用意してあります.
今回はその基本的な使い方について話します.
IdingResrouceとは
IdlingResrouce
とは,android.support.test.espresso
に含まれるインターフェースで,
以下3つの抽象メソッドが定義されています.
-
getName ()
: logなどで使うためのリソースの名前の定義 -
isIdleNow ()
: テストするアクションをいつまで待たせるかの定義 -
registerIdleTransitionCallback()
: コールバックオブジェクトの受け取り
「ある条件を満たしてから,テストアクションを行う」ことをEspressoに指示するためには,
IdlingResourceを実装したクラスを作成して,Espressoに登録する という手順を踏みます.
IdlingResrouceの作成
今回は,「リストにデータがセットされた」という条件を次のように定義します.
public boolean isItemLoaded(RecyclerView list) {
return list.getAdapter()!=null && list.getAdapter().getItemCount() != 0;
}
上の条件をEspressoに伝えるためのIdlingResourceはこうなります.
private class LoadingIdlingResource implements IdlingResource {
private ResourceCallback resourceCallback;
private RecyclerView recyclerView;
private LoadingIdlingResource(RecyclerView recyclerView) {
this.recyclerView = recyclerView;
}
@Override
public String getName() {
return LoadingIdlingResource.class.getSimpleName();
}
@Override
public boolean isIdleNow() {
boolean idle = isItemLoaded(recyclerView);
if (idle && resourceCallback != null) {
resourceCallback.onTransitionToIdle();
}
return idle;
}
@Override
public void registerIdleTransitionCallback(ResourceCallback resourceCallback) {
this.resourceCallback = resourceCallback;
}
private boolean isItemLoaded(RecyclerView list) {
return list.getAdapter()!=null && list.getAdapter().getItemCount() != 0;
}
}
同期のロジックを定義するisIdleNow()
メソッドの定義が主な作業になります.
Espressoは,LoadingIdlingResource.isIdleNow()
を呼んでtrue
が返ってきたら,
次のテストアクションの実行に移ります.
IdlingResourceを使ったテスト
作成したLoadingIdlingResource
を使って,
「リストにデータがセットされたのを確認してから,クリック」
という流れを含むテストはこうなります.
public void testRecyclerView_click() {
// Set up an ActivityMonitor
Instrumentation.ActivityMonitor receiverActivityMonitor =
getInstrumentation().addMonitor(ImageDetailActivity.class.getName(),null, false);
// wait until list item is loaded
IdlingResource idlingResource = new LoadingIdlingResource(mRecyclerView);
Espresso.registerIdlingResources(idlingResource);
// start DetailActivity by clicking RecyclerView item.
Espresso.onView(ViewMatchers.withId(android.R.id.list)).perform(
RecyclerViewActions.actionOnItemAtPosition(0, ViewActions.click()));
// unregister idling resources
Espresso.unregisterIdlingResources(idlingResource);
// Remove the ActivityMonitor
getInstrumentation().removeMonitor(receiverActivityMonitor);
// assertion
Activity activity = receiverActivityMonitor.waitForActivityWithTimeout(1000);
Intent intent = activity.getIntent();
String json = intent.getStringExtra(ImageDetailActivity.EXTRA_CONTENT);
assertEquals(getExpected(), json);
}
終わりに
このブログを参考に実装しました.分かりやすいです.
Square Island: Espresso: Custom Idling Resource
参考URL
EspressoSamples - android-test-kit - Advanced Espresso Samples
Square Island: Espresso: Custom Idling Resource