Robolectric → 现代替代
老写法(Java + Robolectric)
java
@RunWith(RobolectricTestRunner.class)
public class MainActivityTest {
@Test
public void clickButton_updatesText() {
MainActivity activity = Robolectric.buildActivity(MainActivity.class)
.create().start().resume().get();
activity.findViewById(R.id.btn_action).performClick();
TextView tv = activity.findViewById(R.id.tv_result);
assertEquals("已更新", tv.getText().toString());
}
}
问题在哪里
Robolectric 模拟了整个 Android 框架,每次运行加载影子类(Shadow)耗时很长。不同 Android SDK 版本的 shadow 实现差异大,升级 Android 版本时测试经常大量挂掉。大部分团队花在 Robolectric 测试维护上的时间远超它能发现的问题。
新写法(分层测试策略)
kotlin
// 1. 单元测试 --- 测 ViewModel,不测 Activity
class MainViewModelTest {
@Test
fun `updateData refreshes list`() = runTest {
val vm = MainViewModel(fakeRepo)
vm.updateData()
assertEquals(3, vm.items.value?.size)
}
}
// 2. Compose Testing --- 测 UI 逻辑
@Test
fun `click button shows updated text`() = runTest {
composeTestRule.setContent { MyScreen(viewModel) }
composeTestRule.onNodeWithTag("btn_action").performClick()
composeTestRule.onNodeWithTag("tv_result").assertTextEquals("已更新")
}
// 3. 端到端 --- 用 Espresso 或手动在真机上跑
一句话注意
Robolectric 的核心问题------它试图让你相信可以在 JVM 上测试 Android 依赖------但在实践中,维护 Robolectric 测试的成本往往高于收益。更好的替代方案是:
- 把业务逻辑抽到 ViewModel/UseCase,用纯 JUnit + MockK 测(快、稳定)
- UI 逻辑用 Compose Testing 测(不依赖设备、也快)
- 集成测试用真机/模拟器上的 Espresso 跑(慢但可靠,放在 CI 的 nightly build)
Robolectric 的存在意义正在被 Compose Testing + 更好的分层架构替代。
Java Android 老项目迁移系列,持续更新中。