You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从已废弃的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状态。
修复方案
  1. 调整SplashActivity的跳转时机
    将SplashActivity中跳转到MainActivity并销毁自身的逻辑,从onCreate/onStart移动到onResume方法中,保证SplashActivity能够正常走到RESUMED状态,满足ActivityScenarioRule的校验要求。

  2. 手动控制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")));
}
  1. 调整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);
}
  1. 可选:直接测试目标Activity
    如果不需要验证SplashActivity到MainActivity的跳转流程,只需要测试MainActivity的文本展示,可以直接把测试的目标Activity改为MainActivity,省去处理SplashActivity生命周期的麻烦。

内容的提问来源于stack exchange,提问作者tfrysinger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.12 21:18:04