SuperAPI AI 工具集

launching-activities-with-activityscenario

测试与质量

查看项目

更新于 10-16 05:11

技能介绍

用途

本技能用于在 Android 仪器化测试中启动、驱动和销毁 Activity,基于 ActivityScenario 及其 JUnit4 封装 ActivityScenarioRule。它是已废弃 ActivityTestRule 的规范替代方案,提供线程安全、生命周期感知的 Activity 句柄。

适用时机

  • 新建需要 Activity 宿主的仪器化测试。
  • 从已废弃的 ActivityTestRule 迁移并寻找替代方案。
  • 测试因测试 APK 清单缺少 Activity 而报 ActivityNotFoundException。
  • recreate() 测试"丢失"状态,需要调试 remember 与 rememberSaveable 的差异。
  • 向 UI 线程投递操作时测试死锁(onActivity 从错误线程调用)。
  • 测试调用 setResult(...) + finish() 并希望读取 Activity.RESULT_*。

主要能力

  • 启动入口:ActivityScenario.launch(基于类的启动)、launchActivity<T>()(Kotlin reified 扩展)、带显式 Intent 的启动、以及供 setResult + finish 场景使用的 launchActivityForResult。launch 会阻塞调用方直到 Activity 到达 RESUMED。
  • 生命周期驱动:通过 moveToState(Lifecycle.State.*) 在 CREATED、STARTED、RESUMED、DESTROYED 间切换。DESTROYED 为终态,到达后不可回退。
  • 配置变更模拟:recreate() 执行 onSaveInstanceState、销毁并重建 Activity、再执行 onRestoreInstanceState。通过 rememberSaveable / SavedStateHandle / Bundle 存储的状态可保留,普通 remember 与裸 var 字段不会。
  • UI 线程操作:onActivity { activity -> } 在 UI 线程执行并阻塞测试线程直至完成,是直接操作字段和视图的唯一合法方式。
  • 结果读取:通过 scenario.result 读取 Activity.RESULT_*,仅对 launchActivityForResult 启动且已 setResult + finish 的场景有效。
  • JUnit4 封装:ActivityScenarioRule 在 before 调用 launch、在 after 调用 close。
  • 规则排序:与 Hilt 配合时,Hilt 置于最外层(order = 0),ActivityScenarioRule 使用 order = 1 或更高。

使用方式

依赖(Prerequisites)

  • androidTestImplementation("androidx.test:core:1.7.0")(提供 androidx.test.core.app.ActivityScenario)
  • androidTestImplementation("androidx.test.ext:junit:1.3.0")(提供 androidx.test.ext.junit.rules.ActivityScenarioRule)
  • androidTestImplementation("androidx.test:runner:1.7.0") 与 testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
  • 测试 Activity 需在 src/androidTest/AndroidManifest.xml、src/debug/AndroidManifest.xml 或生产清单中声明。

关键规则

  • 必须从 androidx.test.ext.junit.rules 导入 ActivityScenarioRule;androidx.test.rule 包不包含它。
  • 新测试不得使用 ActivityTestRule(已废弃)。
  • 不得从主线程调用 launch、moveToState 或 close,否则会因 instrumentation barrier 永不触发而死锁。
  • 不得在 lambda 之外保存 onActivity 返回的 activity 引用。
  • 不得依赖 Settings.Global.ALWAYS_FINISH_ACTIVITIES 强制 recreation,应使用 scenario.recreate()。
  • 自定义测试 Activity 必须开发者在清单中声明,ui-test-manifest 仅贡献 androidx.activity.ComponentActivity。
  • 必须调用 moveToState(Lifecycle.State.DESTROYED) 或 close(),或使用自动 close 的 ActivityScenarioRule。

关闭方式:使用 ActivityScenarioRule 时 JUnit 自动调用 close();临时启动时可用 Kotlin 的 use { }(scenario 实现 java.io.Closeable)。close() 会将 Activity 驱动到 DESTROYED 且是幂等的。

适用场景

适用于 Android 仪器化测试中需要 Activity 宿主的所有场景,尤其是需要精细化控制生命周期、模拟配置变更、验证状态恢复或读取 Activity 结果的测试。

限制

  • 宿主为 Fragment 时不适用(应使用 FragmentScenario)。
  • 宿主为 androidx.activity.ComponentActivity 的 Compose 测试不适用(createComposeRule() 已封装 scenario)。
  • 需要与系统 UI 或其他应用交互时不适用(应使用 UiAutomator)。
  • 不支持主线程直接调用 launch/moveToState/close。
  • 不遵守 "Don't keep activities" 设置,无法通过该方式测试 recreation。
  • 具体收费、价格、平台等信息资料中暂未提供。