Robolectric 策略

Robolectric 是一个由 Google 维护的开源框架,它允许您在 JVM 内部的模拟 Android 环境中运行测试,而无需仿真器的开销和不稳定。它支持从 Lollipop(API 级别 21)以来的所有 Android 版本。

许多大型项目使用 Robolectric 来提高测试的速度和可靠性,并减少在真实设备或仿真器上运行测试的相关费用。这包括大多数严重依赖 Robolectric 的 Google 应用。

Robolectric 不能完全替代仿真器,因为它不支持所有功能和 API。例如,Robolectric 没有仿真器那样的屏幕,并且某些 API 仅部分受支持。但是,它模拟了 Android 的足够部分,可以可靠地运行单元测试和大多数 UI 测试。

测试策略

您可以通过 Robolectric 采用两种测试策略:单元测试和 UI 测试。

单元测试

Robolectric 被设计为一种在 Android 应用中启用“单元测试”的方式。例如,您可以模拟 Activity 的启动并测试其中的逻辑,调用所有生命周期方法。

您还可以使用 Robolectric 的模拟对象(称为 shadows)作为单元测试的依赖项。例如,如果您的类使用 Bundle 或您需要模拟 蓝牙 连接。

通常,如果您实现可测试架构,则无需使用 Robolectric 进行单元测试,因为您的代码应可在隔离环境中进行测试,不依赖于 Android 框架。

UI 测试

Robolectric 还可以运行 UI 测试,例如 Espresso 或 Compose 测试。您可以通过将仪器化测试移动到 test 源集并设置 Robolectric 依赖项来将其转换为 Robolectric。

android {
  testOptions {
    unitTests {
      isIncludeAndroidResources = true
    }
  }
}

dependencies {
  testImplementation("junit:junit:4.13.2")
  testImplementation("org.robolectric:robolectric:4.13")
}

test 源集中存在的任何 UI 测试都将通过 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)))
     }
}

大多数 UI 测试不与框架交互,您可以在 Robolectric 上运行它们。您可以在 Robolectric 上运行行为测试,因为它所需的保真度已足够。例如,当 Compose 测试验证点击按钮后 UI 是否已更改。

您可以使用 Robolectric 运行其他 UI 测试,例如屏幕截图测试。但是,由于不同设备渲染屏幕的方式略有不同,保真度会较低。

您必须决定 Robolectric 的实现对于每个用例是否足够好,但以下是一些建议

  • 将 Robolectric 用于组件、功能或应用测试的独立 UI 行为测试。通常,这些测试检查 UI 的状态管理和行为,并且不与外部依赖项交互。
  • 在像素精度不重要时,使用 Robolectric 截取屏幕截图。例如,测试组件对不同字体大小或主题的反应。

注意:Robolectric 可以原生截取屏幕截图,但您需要第三方库才能使用它执行屏幕截图测试。

Robolectric 与设备测试

总之,Robolectric 提供了足够的保真度来运行大多数 UI 测试,但某些情况仍需要设备测试,例如与系统 UI 相关(如全面屏或画中画)或依赖于不支持的功能(如 WebView)的情况。