使用测试支持库销毁并重新启动活动

时间:2016-02-10 03:42:15

标签: android testing android-testing testing-support-library

在Android中使用旧的JUnit3样式测试,我可以执行以下操作来破坏并重新启动活动:

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

如何使用新的测试支持库完成同样的事情?我可以使用Espresso和/或UI Automator或新库提供的任何其他机制。

更新

我尝试了以下内容:

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

但是,似乎ActivityTestRule.getActivity()没有重新启动活动。

4 个答案:

答案 0 :(得分:7)

正如@CommonsWare所提到的,自定义规则非常有用。这是我的简单解决方案(可能有许多改进,但这只是一个可以构建的快速框架):

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());
    }
}

请注意,如果您这样做,则此类需要位于包android.support.test.rule中才能访问包私有方法ActivityTestRule#finishActivity。然后在您的测试用例中,实现此规则:

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

然后在您的个别测试用例中,调用actRule.finish()actRule.launchActivity()来终止并重新启动它。或者你可以打电话给actRule.relaunchActivity(),如果你不需要做任何事情来杀死它并再次启动它。注意,如果你有初始启动,你可以传递第三个参数false以延迟启动活动,然后调用actRule.launchActivity()来启动它,但你将失去对一些内置句柄的访问权限作为#afterActivityLaunched#afterActivityFinished()

答案 1 :(得分:2)

正如JCricket和djunod所说,这样做的方法是创建一个自定义规则。我遇到的解决方案的问题是,finishActivity方法受到包保护,您可以在自定义测试规则中使用它。

这是我的解决方案:

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());
  }
}

答案 2 :(得分:0)

一旦我在那里加了一个睡眠,JCricket的回答对我有用......

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) {
            }
        }
    }
}

然后我可以用迭代进行测试:

@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... */ }

答案 3 :(得分:0)

尝试创建自定义规则。在launchActivity(getActivityIntent())方法中调用afterActivityFinished,它将在完成后重新启动活动。

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());
    }
}