跳转至

测试与校验

network-testing 提供 ScriptedNetworkEngine,可以在不访问真实网络的情况下按顺序返回响应、异常、离线、超时和延迟场景。

添加测试依赖

commonTest.dependencies {
    implementation(kotlin("test"))
    implementation("com.catchzoon.network:network-testing:0.1.2-SNAPSHOT")
    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:<coroutines-version>")
}

最小测试

class UserRepositoryTest {
    @Test
    fun loadsUser() = runTest {
        val engine = ScriptedNetworkEngine(
            scenarios = listOf(
                respond(
                    statusCode = 200,
                    body = """{"id":1,"name":"Ada"}""",
                ),
            ),
        )
        val client = engine.client()
        val api = createUserApi(client)

        val result = api.user(1).await()

        assertEquals("Ada", result.getOrThrow().name)
        assertEquals("/users/1", engine.recordedRequests().single().relativePath)
        assertEquals(0, engine.remainingScenarios())
    }
}

测试中显式传入客户端,避免依赖上一个测试残留的全局注册表。

可编排场景

val engine = ScriptedNetworkEngine(
    listOf(
        fail("connection_reset"),
        offline(),
        timeout(),
        delayed(
            delayMillis = 500,
            next = NetworkScenario.Handle { request ->
                NetworkRawResponse(
                    body = request.body,
                    statusCode = 200,
                )
            },
        ),
    ),
)

场景按加入顺序消费。测试结束时断言 remainingScenarios() == 0,可以发现某个分支没有真正发出请求。

应优先覆盖什么

  1. URL、Path、Query、Header 和 Body 是否按接口声明生成;
  2. 401 刷新后是否只重放一次请求;
  3. POST 在没有幂等键时是否不会自动重试;
  4. 缓存命中、过期与 staleIfError 是否符合业务预期;
  5. 取消调用者协程后,引擎是否停止对应请求;
  6. 自定义拦截器、转换器或错误映射器的边界行为。

仓库级验证

Android/JVM 与发布元数据:

./gradlew androidApiCheck \
  :network-core:testDebugUnitTest \
  :network-inspector:testDebugUnitTest \
  :network-realtime:testDebugUnitTest \
  :network-transfer:testDebugUnitTest \
  :network-testing:testDebugUnitTest \
  :network-ksp:test \
  :androidApp:assembleDebug

Apple Silicon Mac 上的 iOS 模拟器运行时测试:

bash scripts/run_ios_simulator_tests.sh

脚本会选择或启动一个可用的 iPhone Simulator,然后实际执行 iosSimulatorArm64Test,而不是只运行 compileKotlinIosSimulatorArm64。除全部 commonTest 外,还会验证 iOS 文件保护、持久缓存/上传/下载状态恢复、 NWPathMonitor 生命周期以及 NSURLSession 平台传输的安全前置条件。

HarmonyOS 的发布产物验证需要 DevEco/OpenHarmony SDK:

DEVECO_STUDIO_HOME=/Applications/DevEco-Studio.app ./scripts/build_harmony.sh har
DEVECO_STUDIO_HOME=/Applications/DevEco-Studio.app ./scripts/build_harmony.sh hap

ohosApp/entry/src/test/NetworkBridgePolicy.test.ets 覆盖 Bridge 方法、文件传输参数、明文 URL、私网/回环地址、 非法方法、超时、响应上限和 Header 注入。Android 单元测试还会执行流式分片上传并核对服务端确认偏移。 CI 默认执行 Harmony 静态门禁;仓库变量 HARMONY_CI_ENABLED=true 且存在 带 self-hosted、macOS、harmony 标签的 DevEco 构建机时,还会实际生成 HAR,并用该 HAR 构建 HAP。

验证口径

平台 默认 CI 专用环境 CI 含义
Android 单元测试、API、APK、Maven/POM 不需要 真正执行 JVM 测试并构建 Android 产物
iOS Apple Silicon iosSimulatorArm64Test、KLib ABI 不需要 真正在 iPhone Simulator 运行 Kotlin/Native 测试
HarmonyOS Bridge/依赖/脚本静态门禁 HAR + 消费 HAR 的 HAP 只有专用 DevEco job 成功才算实际鸿蒙产物通过

Windows/Linux 可以用 -Pkotlin.native.enableKlibsCrossCompilation=true 验证 iOS 源码和测试可编译,但这不等于 iOS 模拟器运行通过;没有 DevEco SDK 时的 Harmony 静态门禁也不等于 HAR/HAP 构建通过。