Skip to content

测试 Compose Multiplatform UI

Compose Multiplatform 中的 UI 测试使用与 Jetpack Compose 测试 API 相同的查找器、断言、操作和匹配器实现。如果你还不熟悉它们,请在继续阅读本文之前,阅读 Jetpack Compose 指南

该 API 处于 实验性的 阶段。 未来可能会有所变化。

Compose Multiplatform 测试与 Jetpack Compose 有何不同

Compose Multiplatform 通用测试 API 不依赖于 JUnit 的 TestRule 类。相反,你需要调用 runComposeUiTest 函数,并在 ComposeUiTest 接收者上调用测试函数。

然而,基于 JUnit 的 API 可用于 桌面目标

使用 Compose Multiplatform 编写和运行测试

首先,为测试添加源代码集,并向模块添加所需的依赖项。然后,编写并运行示例测试,并尝试自定义它。

创建测试源代码集并将测试库添加到依赖项

为了提供具体的示例,本页上的说明遵循 Kotlin Multiplatform 向导 生成的项目结构。如果你正在向现有项目添加测试,你可能需要在路径和命令中将 composeApp 替换为你正在测试的模块名称(例如,shared)。

创建一个通用测试源代码集并添加所需的依赖项:

  1. 创建一个用于通用测试源代码集的目录:composeApp/src/commonTest/kotlin

  2. composeApp/build.gradle.kts 文件中,添加以下配置:

    kotlin
    kotlin {
        //...
        sourceSets { 
            val jvmTest by getting
    
            // 添加通用测试依赖项
            commonTest.dependencies {
                implementation(kotlin("test"))
            
                @OptIn(org.jetbrains.compose.ExperimentalComposeLibrary::class)
                implementation(compose.uiTest)
            }
    
            // 添加桌面测试依赖项
            jvmTest.dependencies { 
                implementation(compose.desktop.currentOs)
            }
        }
    }
  3. 如果你需要为 Android 运行仪器化(模拟器)测试,请按如下方式修改你的 Gradle 配置:

    1. 将以下代码添加到 androidTarget {} 代码块中,以配置仪器化测试源代码集依赖于通用测试源代码集。

      kotlin
      kotlin {
          //...
          androidTarget { 
              @OptIn(ExperimentalKotlinGradlePluginApi::class)
              instrumentedTestVariant.sourceSetTree.set(KotlinSourceSetTree.test)
              //...
          }
          //... 
      }
    2. 按照 IDE 的建议添加任何缺失的导入。

    3. 将以下代码添加到 android.defaultConfig {} 代码块中,以配置 Android 测试仪器化运行器:

      kotlin
      android {
          //...
          defaultConfig {
              //...
              testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
          }
      }
    4. 在根 dependencies {} 代码块中添加所需的依赖项:

      kotlin
      dependencies { 
          androidTestImplementation("androidx.compose.ui:ui-test-junit4-android:1.9.4")
          debugImplementation("androidx.compose.ui:ui-test-manifest:1.9.4")
      }
  4. 在主菜单中选择 Build | Sync Project with Gradle Files,或单击构建脚本编辑器中的 Gradle 刷新按钮。

现在,你已准备好为 Compose Multiplatform UI 编写并运行通用测试。

编写并运行通用测试

composeApp/src/commonTest/kotlin 目录中,创建一个名为 ExampleTest.kt 的文件,并将以下代码复制到其中:

kotlin
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.assertTextEquals
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.performClick
import androidx.compose.ui.test.runComposeUiTest
import kotlin.test.Test

class ExampleTest {

    @OptIn(ExperimentalTestApi::class)
    @Test
    fun myTest() = runComposeUiTest {
        // 声明一个模拟 UI 以演示 API 调用
        //
        // 请替换为你自己的声明以测试项目的代码
        setContent {
            var text by remember { mutableStateOf("Hello") }
            Text(
                text = text,
                modifier = Modifier.testTag("text")
            )
            Button(
                onClick = { text = "Compose" },
                modifier = Modifier.testTag("button")
            ) {
                Text("Click me")
            }
        }

        // 使用 Compose Multiplatform 测试 API 的断言和操作测试所声明的 UI
        onNodeWithTag("text").assertTextEquals("Hello")
        onNodeWithTag("button").performClick()
        onNodeWithTag("text").assertTextEquals("Compose")
    }
}

运行测试:

你有两个选项:

  • 在 Android Studio 中,你可以单击行号槽中 myTest() 函数旁边的绿色运行图标,选择 Run | ExampleTest.myTest,然后选择该测试的 iOS 目标。

  • 在终端中运行以下命令:

    shell
    ./gradlew :composeApp:iosSimulatorArm64Test

在终端中运行此命令:

shell
./gradlew :composeApp:connectedAndroidTest

目前,你无法使用 android (local) 测试配置运行通用 Compose Multiplatform 测试,因此,例如 Android Studio 中的行号槽图标将不起作用。

你有两个选项:

  • 单击行号槽中 myTest() 函数旁边的绿色运行图标,选择 Run | ExampleTest.myTest,然后选择 JVM 目标。

  • 在终端中运行以下命令:

    shell
    ./gradlew :composeApp:jvmTest

在终端中运行此命令:

shell
./gradlew :composeApp:wasmJsTest

接下来

既然你已经掌握了 Compose Multiplatform UI 测试的诀窍,你可能想查看更多与测试相关的资源: