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
)时。