AndroidJUnitRunner

AndroidJUnitRunner 类是一个 JUnit 测试运行程序,可让您在 Android 设备上运行 JUnit 3 或 JUnit 4 型测试类,包括使用 EspressoUI Automator 测试框架的测试类。

此测试运行程序负责将测试软件包和被测应用加载到设备上、运行测试并报告测试结果。此类取代了仅支持 JUnit 3 测试的 InstrumentationTestRunner 类。

此测试运行程序支持几项常见的测试任务,包括:

编写 JUnit 测试

此测试运行程序与 JUnit 3 和 JUnit 4(最高为 JUnit 4.10)测试兼容。不过,您应避免在同一软件包中混用 JUnit 3 和 JUnit 4 测试代码,因为这样可能会导致意外结果。如果要创建要在设备或模拟器上运行的 JUnit 4 插桩测试类,则必须在测试类前面加上 @RunWith(AndroidJUnit4.class) 作为前缀。

以下代码段展示了如何编写 JUnit 4 插桩测试来验证 ChangeTextBehavior 类中的 changeText 操作是否能够正常工作:

Kotlin

    @RunWith(AndroidJUnit4::class)
    @LargeTest
    class ChangeTextBehaviorTest {
        val stringToBeTyped = "Espresso"
        @get:Rule
        val activityRule = ActivityTestRule(MainActivity::class.java)

        @Test fun changeText_sameActivity() {
            // Type text and then press the button.
            onView(withId(R.id.editTextUserInput))
                .perform(typeText(stringToBeTyped), closeSoftKeyboard())
            onView(withId(R.id.changeTextBt)).perform(click())

            // Check that the text was changed.
            onView(withId(R.id.textToBeChanged))
                .check(matches(withText(stringToBeTyped)))
        }
    }
    

Java

    @RunWith(AndroidJUnit4.class)
    @LargeTest
    public class ChangeTextBehaviorTest {

        private static final String stringToBeTyped = "Espresso";

        @Rule
        public ActivityTestRule<MainActivity> activityRule =
                new ActivityTestRule<>(MainActivity.class);

        @Test
        public void changeText_sameActivity() {
            // Type text and then press the button.
            onView(withId(R.id.editTextUserInput))
                    .perform(typeText(stringToBeTyped), closeSoftKeyboard());
            onView(withId(R.id.changeTextBt)).perform(click());

            // Check that the text was changed.
            onView(withId(R.id.textToBeChanged))
                    .check(matches(withText(stringToBeTyped)));
        }
    }
    

使用 Android Test Orchestrator

使用 AndroidJUnitRunner 版本 1.0 或更高版本时,您可以使用一个名为 Android Test Orchestrator 的工具,从而让应用的每个测试在其自己的 Instrumentation 调用中运行。

Android Test Orchestrator 可为您的测试环境提供以下优势:

  • 最小共享状态。 每个测试都在其自己的 Instrumentation 实例中运行。因此,如果您的测试共享应用状态,则每次测试后都会从设备的 CPU 或内存中移除该共享状态的一大部分。

    要在每次测试后从设备的 CPU 和内存中移除全部共享状态,请使用 clearPackageData 标志。

  • 崩溃被隔离。 即使有一个测试崩溃,也只会去掉它自己的 Instrumentation 实例,因此套件中的其他测试仍会运行。

Android Studio 和 Firebase 测试实验室都预安装了 Android Test Orchestrator,但您需要在 Android Studio 中启用该功能

不过,如果您使用其他工具链来测试应用,仍可使用 Android Test Orchestrator,只需完成以下步骤即可:

  1. 在应用的编译文件中添加必要的软件包
  2. 从命令行启用 Android Test Orchestrator。

从 Gradle 启用

要使用 Gradle 命令行工具来启用 Android Test Orchestrator,请完成以下步骤:

  1. 将以下语句添加到项目的 build.gradle 文件:

        android {
          defaultConfig {
           ...
           testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    
           // The following argument makes the Android Test Orchestrator run its
           // "pm clear" command after each test invocation. This command ensures
           // that the app's state is completely cleared between tests.
           testInstrumentationRunnerArguments clearPackageData: 'true'
         }
    
          testOptions {
            execution 'ANDROIDX_TEST_ORCHESTRATOR'
          }
        }
    
        dependencies {
          androidTestImplementation 'androidx.test:runner:1.1.0'
          androidTestUtil 'androidx.test:orchestrator:1.1.0'
        }
  2. 通过执行以下命令来运行 Android Test Orchestrator:

        ./gradlew connectedCheck

从 Android Studio 启用

Android Studio 3.0 及更高版本提供了对 Android Test Orchestrator 的支持。要在 Android Studio 中启用 Android Test Orchestrator,请将从 Gradle 启用部分中所示的语句添加到应用的 build.gradle 文件。

从命令行启用

要在命令行上使用 Android Test Orchestrator,请在终端窗口中运行以下命令:

    # Install the test orchestrator.
    adb install -r path/to/m2repository/androidx/test/orchestrator/1.1.0/orchestrator-1.1.0.apk

    # Install test services.
    adb install -r path/to/m2repository/androidx/test/services/test-services/1.1.0/test-services-1.1.0.apk

    # Replace "com.example.test" with the name of the package containing your tests.
    # Add "-e clearPackageData true" to clear your app's data in between runs.
    adb shell 'CLASSPATH=$(pm path androidx.test.services) app_process / \
      androidx.test.services.shellexecutor.ShellMain am instrument -w -e \
      targetInstrumentation com.example.test/androidx.test.runner.AndroidJUnitRunner \
      androidx.test.orchestrator/.AndroidXTestOrchestrator'
    

如命令语法所示,您先安装 Android Test Orchestrator,然后直接使用它。

注意:如果您不知道目标插桩测试,可以运行以下命令来查询:

    adb shell pm list instrumentation

架构

Orchestrator 服务 APK 存储在与测试 APK 和被测应用的 APK 分离的进程中,如图 1 所示:

图 1. Android Test Orchestrator APK 结构

Android Test Orchestrator 会在测试套件运行开始时收集 JUnit 测试,但随后会在每个测试自己的 Instrumentation 实例中单独执行这些测试。

访问应用上下文

要获取被测应用的上下文,请调用静态 ApplicationProvider.getApplicationContext() 方法。如果您已在应用中创建了 Application 的自定义子类,则此方法会返回自定义子类的上下文。

如果您是工具实现者,则可以使用 InstrumentationRegistry 类来访问低级测试 API。此类包含 Instrumentation 对象、目标应用 Context 对象、测试应用 Context 对象以及传入测试的命令行参数。当您使用 UI Automator 框架编写测试或当您的测试依赖于应用的上下文时,此数据很有用。

过滤测试

在 JUnit 4.x 测试中,您可以使用注解来配置测试运行。此功能可最大限度地减少在测试中添加样板代码和条件代码的需求。除了 JUnit 4 支持的标准注解之外,此测试运行程序还支持 Android 专用注解,包括:

  • @RequiresDevice:指定测试应只能在物理设备上运行,而不能在模拟器上运行。
  • @SdkSuppress:禁止测试在低于给定级别的 Android API 级别上运行。例如,要禁止运行所有低于 23 的 API 级别上的测试,请使用注解 @SDKSuppress(minSdkVersion=23)
  • @SmallTest@MediumTest@LargeTest:对运行测试应需要多长时间进行分类,从而对您可以按多大的频率运行测试进行分类。

将测试分片

此测试运行程序支持将单个测试套件拆成多个分片,以便您可以在同一 Instrumentation 实例下将属于同一分片的测试作为一组轻松地一起运行。每个分片都由一个索引编号进行标识。运行测试时,您可以使用 -e numShards 选项来指定要创建多少个单独的分片,使用 -e shardIndex 选项来指定要运行哪个分片。

例如,要将测试套件拆成 10 个分片并且仅运行分组在第二个分片中的测试,请使用以下命令:

    adb shell am instrument -w -e numShards 10 -e shardIndex 2
    

更多信息

要详细了解如何使用此测试运行程序,请参阅 API 参考文档

要使用 AndroidJUnitRunner 类,请将其添加为项目的一个软件包,如针对 AndroidX Test 设置项目中所述。

其他资源

如需详细了解如何使用 AndroidJUnitRunner,请参阅以下资源。

示例