Robolectric 是由 Google 维护的开源框架,可让您在 JVM 内的模拟 Android 环境中运行测试,而无需承受模拟器的开销和不稳定性。它支持 Lollipop(API 级别 21)及更高版本的 Android。
许多大型项目都使用 Robolectric 来提高测试速度和可靠性,并降低在真实设备或模拟器上运行测试的相关费用。这包括对 Robolectric 严重依赖的大多数 Google 应用。
Robolectric 无法完全取代模拟器,因为它不支持所有功能和 API。例如,Robolectric 没有模拟器那样的屏幕,并且某些 API 仅部分受支持。不过,它模拟了 Android 的足够部分,可靠地运行单元测试和大多数界面测试。
测试策略
您可以使用 Robolectric 采用两种类型的测试策略:单元测试和界面测试。
单元测试
Robolectric 的设计初衷是在 Android 应用中实现“单元测试”。例如,您可以模拟 activity 的启动并测试其中的逻辑,调用所有生命周期方法。
您还可以将 Robolectric 的虚构对象(称为“阴影”)用作单元测试的依赖项。例如,如果您的类使用 Bundle 或您需要模拟 Bluetooth 连接。
一般来说,如果您实现了可测试的架构,则无需使用 Robolectric 进行单元测试,因为您的代码应可单独测试,且不依赖于 Android 框架。
界面测试
Robolectric 还可以运行 界面测试,例如 Espresso 或 Compose 测试。您可以将插桩测试转换为 Robolectric 测试,方法是将其移至 test
源代码集中并设置 Robolectric 依赖项。
android {
testOptions {
unitTests {
isIncludeAndroidResources = true
}
}
}
dependencies {
testImplementation("junit:junit:4.13.2")
testImplementation("org.robolectric:robolectric:4.13")
}
test
源代码集中的任何界面测试都将使用 Robolectric 运行。
import androidx.test.espresso.Espresso.onView
@RunWith(AndroidJUnit4::class)
class AddContactActivityTest {
@Test
fun inputTextShouldBeRetainedAfterActivityRecreation() {
// GIVEN
val contactName = "Test User"
val scenario = ActivityScenario.launchActivity<AddContactActivity>()
// WHEN
// Enter contact name
onView(withId(R.id.contact_name_text))
.perform(typeText(contactName))
// Destroy and recreate Activity
scenario.recreate()
// THEN
// Check contact name was preserved.
onView(withId(R.id.contact_name_text))
.check(matches(withText(contactName)))
}
}
大多数界面测试不会与框架互动,您可以在 Robolectric 上运行这些测试。您可以在 Robolectric 上运行行为测试,因为它所需的保真度已经足够。例如,当 Compose 测试验证点击按钮后界面是否发生变化时。
您可以使用 Robolectric 运行其他界面测试,例如屏幕截图测试。不过,由于不同设备呈现屏幕的方式略有不同,因此保真度较低。
您必须确定 Robolectric 的实现是否足以满足每种用例,但下面有一些建议:
- 使用 Robolectric 对组件、功能或应用测试进行隔离的界面行为测试。通常,这些测试会检查界面的状态管理和行为,而不会与外部依赖项进行交互。
- 当像素精确度不重要时,请使用 Robolectric 截取屏幕截图。例如,测试组件对不同字体大小或主题的响应。
注意:Robolectric 可以原生截取屏幕截图,但您需要第三方库才能使用它执行屏幕截图测试。
Robolectric 与设备测试
总而言之,Robolectric 提供足够的保真度来运行大多数界面测试,但在某些情况下仍需要进行设备测试,例如与系统界面(例如边到边或画中画)相关的测试,或者在依赖于不受支持的功能(例如 WebView
)时。