从已废弃的ActivityTestRule切换为ActivityScenarioRule后Espresso测试失败
问题产生原因
- ActivityScenarioRule 对启动的Activity生命周期校验更严格。它默认会等待指定启动的Activity(也就是你代码里的SplashActivity)达到
RESUMED状态才会继续执行测试代码。如果你的SplashActivity在onCreate或者onStart阶段就已经调用finish()销毁自己跳转到MainActivity,永远不会走到RESUMED生命周期,就会触发这个报错。而旧的ActivityTestRule没有这种严格的生命周期等待校验,所以可以正常运行。 - IdlingResource注册时机不当。
@Before注解的方法执行时机早于Activity的启动流程,如果你提前注册了自定义的IdlingResource,Espresso在启动Activity的过程中就会开始检查IdlingResource的空闲状态,如果此时IdlingResource的计数逻辑和Activity生命周期触发顺序冲突,就会导致死锁,永远无法触发SplashActivity的生命周期回调,卡在PRE_ON_CREATE状态。
修复方案
调整SplashActivity的跳转时机
将SplashActivity中跳转到MainActivity并销毁自身的逻辑,从onCreate/onStart移动到onResume方法中,保证SplashActivity能够正常走到RESUMED状态,满足ActivityScenarioRule的校验要求。手动控制Activity启动流程,关闭自动启动校验
修改ActivityScenarioRule的配置,关闭自动启动,测试时手动控制Activity的启动,无需等待其达到RESUMED状态:
// 第三个参数设为false,关闭Activity自动启动 @Rule public ActivityScenarioRule<SplashActivity> mActivityTestRule = new ActivityScenarioRule<>(SplashActivity.class, null, false); @Test public void splashActivityTest() { // 手动启动Activity,无需等待生命周期达到RESUMED mActivityTestRule.getScenario().launchActivity(new Intent()); // 原有断言逻辑不变 ViewInteraction textView = onView( allOf(withId(R.id.playlistText), withText("My Playlists"), withParent(withParent(withId(R.id.nav_host_fragment))), isDisplayed())); textView.check(matches(isDisplayed())); ViewInteraction textView2 = onView( allOf(withId(R.id.playlistText), withText("My Playlists"), withParent(withParent(withId(R.id.nav_host_fragment))), isDisplayed())); textView2.check(matches(withText("My Playlists"))); }
- 调整IdlingResource注册时机
移除@Before方法中的IdlingResource注册逻辑,改为在SplashActivity启动后再注册,避免提前注册导致的死锁:
@Before public void registerIdlingResource() { // 移除原有注册逻辑,放到Activity启动后执行 } @Test public void splashActivityTest() { mActivityTestRule.getScenario().onActivity(activity -> { // 当Activity实例创建后再注册IdlingResource IdlingRegistry.getInstance().register(CountingIdlingResourceSingleton.espressoIdlingResource); }); // 原有断言逻辑不变 } @After public void unregisterIdlingResource() { IdlingRegistry.getInstance().unregister(CountingIdlingResourceSingleton.espressoIdlingResource); }
- 可选:直接测试目标Activity
如果不需要验证SplashActivity到MainActivity的跳转流程,只需要测试MainActivity的文本展示,可以直接把测试的目标Activity改为MainActivity,省去处理SplashActivity生命周期的麻烦。
内容的提问来源于stack exchange,提问作者tfrysinger
相关产品推荐
相关产品推荐

