在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()
没有重新启动活动。
答案 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());
}
}