Compose UI Test中后台任务刷新测试指南 - 第1节

1.1 原理与背景

Compose UI Test 是 Jetpack Compose 官方提供的声明式 UI 测试框架,允许开发者以纯 Kotlin DSL 方式与 Compose 界面交互、验证状态变化和异步行为。在后台任务刷新测试场景中,测试环境需要同时满足三个条件:Compose 运行时可见、异步任务调度可控、测试依赖与生产分离。本章围绕环境搭建,建立从 Gradle 配置到模拟器编译的核心链路,为后续章节(如 IdlingResource、协程测试)提供基础设施。

核心依赖关系:ui-test-junit4 提供 ComposeTestRule 和 createComposeRule();ui-test-manifest 负责在 debug 构建中注入测试 Intent 处理能力;kotlinx-coroutines-test 用于控制协程调度器。所有依赖必须放在 androidTestImplementation 或 debugImplementation 配置下,避免发布包携带测试库。

Compose UI Test 仅支持 API 21+ 的真机或模拟器;推荐使用 Android 14 (API 34) 模拟器进行验证。
Compose UI Test 环境搭建组件关系图 Compose UI Test 环境搭建组件关系 编译环境 (Gradle 配置) app/build.gradle (Module) testOptions { includeAndroidResources = true } ui-test-junit4 / ui-test-manifest / coroutines-test 测试运行环境 模拟器 / 真机 (API 21+) Android Compile SDK 34 src/androidTest/ 测试代码目录 依赖传递 可运行:gradlew connectedAndroidTest

1.2 完整实现步骤

1.2.1 创建测试目录结构

在 app 模块的 src/ 下建立标准 Android 测试文件夹:

app/
├─ src/
│  ├─ main/
│  │  └─ java/com/example/app/
│  ├─ test/                    # 单元测试(本地 JVM)
│  │  └─ java/com/example/app/
│  └─ androidTest/             # 仪器化测试(真机/模拟器)
│     └─ java/com/example/app/
│        └─ ExampleComposeTest.kt
└─ build.gradle.kts  (或 build.gradle)
务必使用 androidTest 目录存放 Compose UI Test,否则 ComposeTestRule 无法获取 Activity 上下文。

1.2.2 配置 build.gradle 依赖

Module 级 build.gradle (Groovy 示例):

android {
    compileSdk 34

    defaultConfig {
        minSdk 21
        targetSdk 34
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    testOptions {
        unitTests.includeAndroidResources = true
    }

    buildFeatures {
        compose true
    }

    composeOptions {
        kotlinCompilerExtensionVersion = "1.5.15"
    }
}

dependencies {
    // Compose BOM(统一版本管理)
    implementation platform("androidx.compose:compose-bom:2024.10.01")
    implementation "androidx.compose.ui:ui"

    // Compose UI Test (仪器化)
    androidTestImplementation platform("androidx.compose:compose-bom:2024.10.01")
    androidTestImplementation "androidx.compose.ui:ui-test-junit4"
    androidTestImplementation "androidx.compose.ui:ui-test-manifest"

    // 协程测试(用于后台任务模拟)
    testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.1"

    // 可选:MockK 用于 mock 后台仓库
    androidTestImplementation "io.mockk:mockk-android:1.13.10"
}

Kotlin DSL (build.gradle.kts) 版本:

android {
    compileSdk = 34
    defaultConfig {
        minSdk = 21
        targetSdk = 34
        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
    }
    testOptions {
        unitTests.isIncludeAndroidResources = true
    }
    buildFeatures { compose = true }
    composeOptions {
        kotlinCompilerExtensionVersion = "1.5.15"
    }
}

dependencies {
    val composeBom = platform("androidx.compose:compose-bom:2024.10.01")
    implementation(composeBom)
    androidTestImplementation(composeBom)

    implementation("androidx.compose.ui:ui")
    androidTestImplementation("androidx.compose.ui:ui-test-junit4")
    androidTestImplementation("androidx.compose.ui:ui-test-manifest")
    testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.1")
    androidTestImplementation("io.mockk:mockk-android:1.13.10")
}

1.3 关键配置与 API 参数

配置项说明推荐值
testInstrumentationRunner仪器化测试运行器androidx.test.runner.AndroidJUnitRunner
ui-test-junit4Compose 测试规则 (JUnit4)1.6.8 (通过 BOM 控制)
ui-test-manifestdebug 构建注入测试 Intent与 ui-test-junit4 同版本
compose-bom统一管理 Compose 库版本2024.10.01 或更高
compileSdk编译目标 API34(Android 14)
minSdk最低支持 API21

ComposeTestRule 重要 API:

  • createComposeRule() — 创建标准测试规则
  • createAndroidComposeRule<MainActivity>() — 绑定具体 Activity
  • waitForIdle() — 等待 Compose 渲染空闲(需要配合 IdlingResource)
  • onNodeWithText() / onNodeWithTag() — 节点查找

1.4 常见问题与调试技巧

⚠️ Gradle 版本冲突
如果遇到 KotlinCompilerExtensionVersion 与 Compose BOM 不匹配,优先升级 BOM 版本。检查 ./gradlew :app:dependencies --configuration androidTestRuntimeClasspath 查看冲突。
  • 问题:测试运行提示 "No tests found" — 检查测试方法是否添加 @Test 注解且方法可见性为 @Test。确认测试目录是 androidTest 而非 test。
  • 问题:模拟器启动后 Compose 内容无法渲染 — 确保模拟器使用 API 21+ 且启用了 GPU 加速(设置 -> 高级 -> GPU 渲染模式)。
  • 问题:AlarmManager 或 Handler 后台任务无法在测试中触发 — 使用 compose :ui-test-manifest 后,测试框架会拦截系统服务。推荐改用协程 + StandardTestDispatcher。
  • 调试技巧:在测试中临时添加 Thread.sleep(2000) 可以肉眼观察界面状态;但正式用例应使用 waitForIdle() 或 idlingResource。

1.5 可验证的测试结果与日志

1.5.1 验证 Gradle 配置正确性

运行以下命令检查依赖是否成功解析:

./gradlew :app:dependencies --configuration androidTestRuntimeClasspath | grep -E "compose|ui-test"

预期输出片段(示例):

androidTestRuntimeClasspath - Resolved configuration for runtime classpath.
--- androidx.compose.ui:ui-test-junit4:1.6.8
--- androidx.compose.ui:ui-test-manifest:1.6.8
--- io.mockk:mockk-android:1.13.10--- org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.1

1.5.2 编写最小验证测试

// app/src/androidTest/java/com/example/app/EnvironmentVerificationTest.kt
package com.example.app

import androidx.compose.material3.Text
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithText
import org.junit.Rule
import org.junit.Test

class EnvironmentVerificationTest {

    @get:Rule
    val composeTestRule = createComposeRule()

    @Test
    fun verifyComposeTestEnvironment() {
        composeTestRule.setContent {
            Text("Hello Compose UI Test")
        }
        composeTestRule.onNodeWithText("Hello Compose UI Test").assertExists()
    }
}

运行测试:

./gradlew :app:connectedAndroidTest

成功日志示例:

> Task :app:connectedDebugAndroidTest
Starting 1 tests on Pixel_6_API_34(AVD) - 14
Tests on Pixel_6_API_34(AVD) - 14 passed: 1
Tests on Pixel_6_API_34(AVD) - 14 failed: 0
BUILD SUCCESSFUL in 1m 47s

若控制台输出类似 BUILD SUCCESSFUL 且无测试失败,说明 Compose UI Test 环境已正确搭建。