Destroy and restart Activity with Testing Support Library

雨燕双飞 提交于 2019-11-28 00:12:07

问题


Using the old JUnit3-style tests in Android, I could do the following to destory and restart an activity:

Instrumentation inst = getInstrumentation();
Activity activity = inst.getActivity();
// do something
activity.finish();
Assert.assertTrue(this.activity.isFinishing());
activity = inst.getActivity();
// assert that activity's state is restored

How can I accomplish the same thing using the new Testing Support Library? I'm fine with using either Espresso and/or UI Automator or any other mechanism provided by the new library.

Update:

I tried the following:

Activity activity = activityTestRule.getActivity();
// do something
activity.finish();
Assert.assertTrue(this.activity.isFinishing());
activity = activityTestRule.getActivity();
// assert that activity's state is restored

However, it appears that ActivityTestRule.getActivity() does not restart the activity.


回答1:


As @CommonsWare mentioned, a custom rule is pretty useful. Here's my simple solution (many improvements are possible, but this is just a quick framework that can be built on):

public class ControlledActivityTestRule<T extends Activity> extends ActivityTestRule<T> {
    public ControlledActivityTestRule(Class<T> activityClass) {
        super(activityClass, false);
    }

    public ControlledActivityTestRule(Class<T> activityClass, boolean initialTouchMode) {
        super(activityClass, initialTouchMode, true);
    }

    public ControlledActivityTestRule(Class<T> activityClass, boolean initialTouchMode, boolean launchActivity) {
        super(activityClass, initialTouchMode, launchActivity);
    }

    public void finish() {
        finishActivity();
    }

    public void relaunchActivity() {
        finishActivity();
        launchActivity();
    }

    public void launchActivity() {
        launchActivity(getActivityIntent());
    }
}

Note, if you do it like this, this class needs to be in the package android.support.test.rule to access the package private method ActivityTestRule#finishActivity. Then in your test case, implement this rule:

@Rule
public ControlledActivityTestRule<TestFountainPreferenceActivity> actRule = new ControlledActivityTestRule<>(TestFountainPreferenceActivity.class);

Then in your individual test case, call actRule.finish() and actRule.launchActivity() to kill and restart it. Or you can call actRule.relaunchActivity() if you don't need to do anything in between killing it and starting it up again. Note, you can pass the third parameter false to delay starting the activity if you have initial startup, and then call actRule.launchActivity() to get it going, but you will loose access to some of the built in handles such as #afterActivityLaunched and #afterActivityFinished().




回答2:


As JCricket and djunod says the way to do it is creating a custom rule. The problem that I faced with their solutions is that the method finishActivity is package protected and you can use it in your custom test rule.

This is my solution:

public class RelaunchActivityRule<T extends Activity> extends ActivityTestRule<T> {

  public RelaunchActivityRule(Class<T> activityClass) {
    super(activityClass,false);
  }

  public RelaunchActivityRule(Class<T> activityClass, boolean initialTouchMode) {
    super(activityClass, initialTouchMode,true);
  }

  public RelaunchActivityRule(Class<T> activityClass, boolean initialTouchMode,
      boolean launchActivity) {
    super(activityClass, initialTouchMode, launchActivity);
  }

  @Override protected void afterActivityFinished() {
    super.afterActivityFinished();
    launchActivity(getActivityIntent());
  }
}



回答3:


JCricket's answer worked for me once I added a sleep in there...

package android.support.test.rule;

public class ControlledActivityTestRule<T extends Activity> extends ActivityTestRule<T> {
    public ControlledActivityTestRule(Class<T> activityClass) {
        super(activityClass, false);
    }

    public ControlledActivityTestRule(Class<T> activityClass, boolean initialTouchMode) {
        super(activityClass, initialTouchMode, true);
    }

    public ControlledActivityTestRule(Class<T> activityClass, boolean initialTouchMode, boolean launchActivity) {
        super(activityClass, initialTouchMode, launchActivity);
    }

    public void finish() {
        finishActivity();
    }

    public void relaunchActivity(int seconds) {
        finishActivity();
        sleep(seconds);
        launchActivity();
        sleep(seconds);
    }

    public void launchActivity() {
        launchActivity(getActivityIntent());
    }

    public void sleep(int seconds) {
        if (seconds > 0) {
            try {
                Thread.sleep(seconds * 1000);
            } catch (Exception ex) {
            }
        }
    }
}

I was then able to do a test with iterations:

@Rule
public ControlledActivityTestRule<MainActivity> mActivityRule = new ControlledActivityTestRule<>(MainActivity.class);

@Test
public void testOAA310() {
    int count = 1000;
    for (int i = 0; i < count; i++) {
        testCaseOAA310();
        mActivityRule.relaunchActivity(5);
    }
}

void testCaseOAA310() { /* ... blah blah blah... */ }



回答4:


Try creating a custom rule. Call launchActivity(getActivityIntent()) in afterActivityFinished method, it will restart the activity after finish.

public class RestartActivityRule<T extends Activity> extends ActivityTestRule<T> {

    public RestartActivityRule(Class<T> activityClass) {
        super(activityClass,false);
    }

    public RestartActivityRule(Class<T> activityClass, boolean initialTouchMode) {
        super(activityClass, initialTouchMode,true);
    }

    public RestartActivityRule(Class<T> activityClass, boolean initialTouchMode,
      boolean launchActivity) {
        super(activityClass, initialTouchMode, launchActivity);
    }

    @Override protected void afterActivityFinished() {
        super.afterActivityFinished();
        launchActivity(getActivityIntent());
    }
}


来源:https://stackoverflow.com/questions/35306423/destroy-and-restart-activity-with-testing-support-library

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!