- public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {
- public MainActivityTest() {
- super(MainActivity.class);
- }
- @Override
- public void setUp() throws Exception {
- super.setUp();
- // Espresso will not launch our activity for us, we must launch it via
- // getActivity().
- getActivity();
- }
- public void testDrawerOpen() {
- // Drawer open
- onView(withId(android.R.id.home)).perform(click());
- // Click Settings
- onView(withId(R.id.settings)).perform(click());
- }
- }
ところが、これはテストに失敗します。
onView(withId(R.id.settings)).perform(click());
のところで、そんな Id の View は見つからないと言われてしまいます。
原因は、Navigation Drawer が開き終わる前に View を探そうとするからです。
そこで、Navigation Drawer が開き(または閉じ)はじめてから、閉じる(または開く)まで、 Espresso に今は Idle 状態じゃないと伝えるようにします。
まず、IdlingResource インタフェースを実装したクラスのインスタンスを用意し、Espresso.registerIdlingResources()で登録します。
IdlingResource を実装したクラスとして、CountingIdlingResource が用意されています。
このクラスは内部でカウンターを持っていて、increment() と decrement() でカウンターの値を変え、カウンターが 0 のときが Idle 状態として Espresso に伝えられます。
Navigation Drawer を実現している DrawerLayout クラスの DrawerListener.onDrawerStateChanged() を利用して、カウンターの値を変えるようにします。
そのため、テスト対象の Activity に口を用意しないといけません。
- public class MainActivity extends ActionBarActivity implements DrawerListener {
- private DrawerLayout mDrawerLayout;
- private View mDrawerContainer;
- private ActionBarDrawerToggle mDrawerToggle;
- private DrawerFragment mDrawerFragment;
- /**
- * Espresso で Drawer を開くため
- */
- public interface DrawerStateListener {
- public void onDrawerStateChanged(int newState);
- }
- private DrawerStateListener mDrawerStateListener;
- public void setDrawerListener(DrawerStateListener l) {
- mDrawerStateListener = l;
- }
- public DrawerStateListener getDrawerListener() {
- return mDrawerStateListener;
- }
- /**
- *
- */
- @Override
- protected void onCreate(Bundle savedInstance) {
- super.onCreate(savedInstance);
- setContentView(R.layout.activity_main);
- mDrawerFragment = (DrawerFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_drawer);
- mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
- mDrawerContainer = findViewById(R.id.left_drawer);
- mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, R.drawable.ic_drawer,
- R.string.drawer_open, R.string.drawer_close) {
- @Override
- public void onDrawerClosed(View drawerView) {
- supportInvalidateOptionsMenu();
- super.onDrawerClosed(drawerView);
- }
- @Override
- public void onDrawerOpened(View drawerView) {
- supportInvalidateOptionsMenu();
- super.onDrawerOpened(drawerView);
- }
- @Override
- public void onDrawerStateChanged(int newState) {
- if (mDrawerStateListener != null) {
- mDrawerStateListener.onDrawerStateChanged(newState);
- }
- super.onDrawerStateChanged(newState);
- }
- };
- mDrawerLayout.setDrawerListener(mDrawerToggle);
- getSupportActionBar().setDisplayHomeAsUpEnabled(true);
- getSupportActionBar().setHomeButtonEnabled(true);
- }
- ...
- }
この DrawerStateListener を実装した DrawerStateListenerImpl クラスを用意し、onDrawerStateChanged(int newState) で newState の値に応じて increment(), decrement() します。 このテストでは Navigation Drawer 部分をドラッグしないので DrawerLayout.STATE_DRAGGING は無いと思って簡略化しています。
setUp() の中で getActivity() で取得した Activity に対して DrawerStateListenerImpl のインスタンスを差し込み、registerIdlingResources() で DrawerStateListenerImpl で参照している CountingIdlingResource のインスタンスを登録しています。
- public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {
- public MainActivityTest() {
- super(MainActivity.class);
- }
- private class DrawerStateListenerImpl implements DrawerStateListener {
- private final DrawerStateListener realDrawerListener;
- private final CountingIdlingResource mIdlingResource;
- private DrawerStateListenerImpl(DrawerStateListener l, CountingIdlingResource idlingResource) {
- this.realDrawerListener = l;
- this.mIdlingResource = checkNotNull(idlingResource);
- }
- @Override
- public void onDrawerStateChanged(int newState) {
- // ドラッグしないので
- if (newState != DrawerLayout.STATE_IDLE) {
- mIdlingResource.increment();
- } else {
- mIdlingResource.decrement();
- }
- if (realDrawerListener != null) {
- realDrawerListener.onDrawerStateChanged(newState);
- }
- }
- }
- @Override
- public void setUp() throws Exception {
- super.setUp();
- // Espresso will not launch our activity for us, we must launch it via
- // getActivity().
- MainActivity activity = getActivity();
- CountingIdlingResource countingResource = new CountingIdlingResource("DrawerCalls");
- activity.setDrawerListener(new DrawerStateListenerImpl(activity.getDrawerListener(), countingResource));
- registerIdlingResources(countingResource);
- }
- public void testDrawerOpen() {
- // Drawer open
- onView(withId(android.R.id.home)).perform(click());
- // Click Settings
- onView(withId(R.id.settings)).perform(click());
- }
- }
0 件のコメント:
コメントを投稿