第 13 章:测试、CI 与发布边界
1. 测试不是只测组件快照
这条链路的关键风险在跨层协议和时序,因此测试按四类分布:
| 类别 | 代表测试 | 保护目标 |
|---|---|---|
| 协议纯函数 | HomeContainerProtocol.test.ts | intent parse、owner、tab invariant |
| ViewModel | mobileNativeHomeViewModelAdapter.test.ts | loading/ready/empty、稳定 presentation、row mapping |
| 并发/投影 | nativeHomePortfolioRequestLifecycle.test.ts、AllNetwork tests | stale owner、single-flight、authoritative response、dedupe |
| 原生合同 | Swift HomeContainerStateContract.swift、Kotlin HomeContainerStateTest | JS JSON 能否被两端实际 decoder 接受 |
2. 合同测试的最小闭环
.github/workflows/native-home-contract.yml 的 iOS job 在 macOS 15 编译 Swift 模型和合同程序;Android job 安装 Yarn dependencies、配置 JDK 17,然后运行指定 Kotlin unit test。它不是模拟测试,而是直接把同一个 fixture 交给两种原生 decoder。
3. 为什么 fixture 比三个独立样例更好
同一个 fixture 可以发现:
- TS 允许但 Swift 不允许的 optional/enum 形状;
- Kotlin
optString/optInt的默认值是否与 JS 约定一致; handofftab 是否错误携带 sections;- selected tab 是否意外指向 handoff;
- theme color、nested array、action/segment 的字段是否缺失。
它把“协议漂移”从线上 UI bug 提前变成 CI failure。
4. ViewModel 测试体现的产品语义
测试标题本身就是设计文档,例如:
- “keeps committed tab topology while a replacement owner is loading” —— owner loading 不能马上把 tab topology 降级成 Spot-only;
- “strips owner commands” —— 视觉保留不等于旧动作仍可执行;
- “shows funded actions before final balance total settles” —— action row 不必等待所有金额字段 authoritative;
- “keeps loading action geometry aligned with funded row” —— loading 是几何稳定性问题;
- “renders UTXO change outputs as one net transfer” —— History 展示是语义投影,不是原始 transfer 数组直出。
5. 快照持久化测试的工程含义
homeDisplaySnapshotCodec.test.ts 检查 byte length、schema、分区、allowlist、默认值恢复和 row projection;homeDisplaySnapshotPersistQueue.test.ts 检查 generation coalescing、并发 route index、旧 chunk 清理和 confirmed header 保护。
这些测试说明持久化协议的目标是“可恢复的展示缓存”,不是“把 live store 做成第二数据库”。
6. 修改协议时的检查清单
text
[ ] TS types + invariant
[ ] TS intent parser
[ ] HomeContainer.nitro.ts
[ ] Nitrogen codegen / generated config
[ ] Swift model + invariant
[ ] Kotlin model + invariant
[ ] fixture
[ ] HomeContainerProtocol tests
[ ] Swift contract script
[ ] Kotlin contract workflow
[ ] ViewModel snapshot / intent tests
[ ] Android / iOS slot layout tests if geometry changed7. CI 的监听范围
workflow 的 paths 包含:
apps/mobile/src/home/**packages/native-components/**packages/kit/src/views/Home/**- 两个 protocol script
package.json、yarn.lock
这组路径准确反映了功能边界:改 renderer、协议、原生实现、Home 业务和依赖都要重新验证。