Android UI测试中如何避免@Test间重启应用,实现用例连续执行?
Android UI测试避免应用重启,连续执行测试用例的方案
核心原因
默认情况下,Espresso的@Rule注解测试规则(如ActivityTestRule或ActivityScenarioRule)会在每个@Test方法执行前重启应用/Activity——这是因为每个测试方法都会重新初始化测试规则实例,触发应用进程重启。
解决方法:使用类级别测试规则(@ClassRule)
将测试规则从方法级别的@Rule改为类级别的@ClassRule,这样整个测试类生命周期内只会启动一次应用,所有@Test方法共享同一个应用进程和Activity实例。
步骤1:定义ClassRule
以AndroidX Test推荐的ActivityScenarioRule为例:
import androidx.test.ext.junit.rules.ActivityScenarioRule; import org.junit.ClassRule; public class OnboardingTest { // 类级别规则,整个测试类仅启动一次Activity @ClassRule public static ActivityScenarioRule<OnboardingActivity> scenarioRule = new ActivityScenarioRule<>(OnboardingActivity.class); }
若使用旧版ActivityTestRule:
import androidx.test.rule.ActivityTestRule; import org.junit.ClassRule; public class OnboardingTest { @ClassRule public static ActivityTestRule<OnboardingActivity> activityRule = new ActivityTestRule<>(OnboardingActivity.class, true, true); }
步骤2:手动重置测试状态
应用不会自动重启,前一个测试的状态(如引导流程已完成的标记)会影响后续测试,因此需要在每个测试方法执行前重置到初始状态:
import android.content.Context; import android.content.SharedPreferences; import androidx.test.platform.app.InstrumentationRegistry; import org.junit.Before; public class OnboardingTest { // ... 上述ClassRule定义 ... @Before public void resetOnboardingState() { // 1. 清除标记引导完成的SharedPreferences(根据应用实际存储键修改) Context targetContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); SharedPreferences onboardingPrefs = targetContext.getSharedPreferences("onboarding_status", Context.MODE_PRIVATE); onboardingPrefs.edit().remove("has_completed_onboarding").apply(); // 2. 重置Activity到引导页起点 scenarioRule.getScenario().recreate(); // 若使用ActivityTestRule: // activityRule.getActivity().finish(); // activityRule.launchActivity(null); } // 测试引导页第一步 @Test public void testOnboardingStep1() { onView(withId(R.id.btn_next)).perform(click()); onView(withId(R.id.step2_layout)).check(matches(isDisplayed())); } // 测试引导页第二步 @Test public void testOnboardingStep2() { onView(withId(R.id.checkbox_agree)).perform(click()); onView(withId(R.id.btn_finish)).perform(click()); onView(withId(R.id.main_layout)).check(matches(isDisplayed())); } }
关键注意事项
- 测试独立性:每个
@Test方法必须独立,即使共享应用进程,也要通过@Before确保初始状态一致,避免测试间状态污染。 - 执行顺序:测试方法的执行顺序默认不固定,不要依赖前一个测试的结果完成当前测试。
- 资源清理:若测试涉及数据库、文件等持久化数据,需在
@Before或@After中同步清理。
内容的提问来源于stack exchange,提问作者Gábor Tachtler
相关产品推荐
相关产品推荐

