Files
brainwave/docs/quality-gates.md
T

157 lines
6.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 质量门禁与验证策略
> 状态:测试策略已定义;命令在 Android 骨架初始化后启用
> 原则:完成必须有可重复证据,不能以“代码看起来正确”代替验证
## 1. 反馈循环
每个实现任务遵循:
```text
需求编号 → 最小实现 → 就近测试 → 全量静态/单元检查 → 设备验证 → 文档同步
↑ ↓
└──── 失败归因与修复 ────┘
```
同类失败第二次出现时,应更新[失败记忆](failure-memory.md);适合机械检查的规则必须转成测试、lint 或脚本。
## 2. 预期本地命令
工程创建后,Windows 环境至少提供以下稳定入口:
```powershell
.\gradlew.bat spotlessCheck
.\gradlew.bat lintDebug
.\gradlew.bat testDebugUnitTest
.\gradlew.bat assembleDebug
.\gradlew.bat connectedDebugAndroidTest
```
若采用不同格式化插件,命令可以调整,但必须在本文件和 CI 同步更新。`connectedDebugAndroidTest` 需要模拟器或设备,应与纯 JVM 快速门禁分开。
建议再提供聚合任务:
```powershell
.\gradlew.bat verifyLocal
```
它至少依赖格式、lint、JVM 单元测试和 debug 构建,使代理不必猜测正确验证组合。
当前仓库没有 Gradle Wrapper,所以上述命令尚未运行,也不能报告为通过。
## 3. 测试层次
### 3.1 纯 JVM 领域测试(最快,阻塞合并)
- 三枚铜币 8 种排列映射。
- 六爻 4,096 种组合不变量。
- 64 卦模式映射唯一性。
- bottom-up 顺序和显示适配。
- `CastResult` 序列化往返。
- 本地内容 schema 与完整性。
- 本地解释模板选择。
- AI DTO schema、长度和纯文本校验。
### 3.2 ViewModel/Repository 测试(阻塞合并)
- 投币状态机、返回修改和第六次封印。
- SavedState 恢复。
- 只在用户点击且同意后调用 AI。
- 并发点击、取消和超时不重复提交。
- Room 保存/读取一致性。
- 删除与撤销/确认行为。
测试优先使用接口的 fake 实现,不依赖真实网络和实时模型。
### 3.3 Compose UI 测试(阻塞发布)
- 首次说明与方法约定可达。
- 六轮录入的进度、按钮启用状态和错误恢复。
- 结果页本卦/之卦/动爻语义。
- AI 同意、加载、失败、本地降级。
- 最大字体下关键操作可到达。
- TalkBack 语义、焦点顺序和触控目标。
- 旋转/横屏/大屏布局。
### 3.4 端到端与人工验收(阻塞发布)
- 飞行模式走完整核心流程。
- 真机上检查输入法、返回手势、深浅主题和触觉。
- 使用已知六爻夹具人工核对卦象绘制和文本。
- 后端 staging 环境验证同意、超时、限流、非法响应和安全分支。
- 验证安装包不包含生产密钥和未授权内容。
## 4. 需求追踪矩阵
| 需求 | 主要自动化证据 | 人工证据 |
|---|---|---|
| FR-Q-001~004 | ViewModel + Compose 输入测试 | 中文输入法、隐私文案 |
| FR-C-001~003 | 状态机与 UI 测试 | 真实投币录入可理解性 |
| FR-C-004~006 | 领域穷举与映射测试 | 已知卦象目视复核 |
| FR-C-007 | SavedState/重建测试 | 旋转、切后台、进程恢复 |
| FR-R-001~003 | UI 语义与 screenshot 测试 | TalkBack、色觉与长文阅读 |
| FR-R-004 | 网络失败测试 | 飞行模式 |
| FR-R-005 | 内容 schema/授权清单检查 | 内容负责人签核 |
| FR-E-001~003 | 网络调用次数与同意状态测试 | 首次同意流程 |
| FR-E-004~006 | 输出 schema + 安全用例集 | 安全/产品审核 |
| FR-H-001~004 | Room、删除、权限边界测试 | 隐私设置与删除体验 |
| NFR-OFF-001 | fake/offline 集成测试 | 飞行模式真机 |
| NFR-DET-001 | 4,096 组合属性测试 | 无 |
| NFR-SEC/PRI | secret scan、日志测试 | APK/代理抓包复核 |
| NFR-A11Y-001 | Compose accessibility checks | TalkBack、最大字体 |
| NFR-RES-001 | 重建和恢复测试 | 厂商设备抽测 |
## 5. 架构与数据门禁
工程初始化时应新增可机械执行的规则:
- domain 包不得依赖 Android、Compose、Room 和网络包。
- `data.ai` 不得依赖或调用 `CastEngine`。
- feature UI 不得引用 DAO 或网络 DTO。
- 生产源码不得出现 API key 形态、真实用户问题测试样例或 HTTP body logger。
- 内容校验任务验证 64 卦、384 条爻辞、唯一模式、来源和许可证字段。
- 文档链接和需求编号无悬空引用。
可以使用现有静态工具、架构测试库或小型自定义 Gradle 任务;具体选型写入[决策记录](decisions.md)。规则的错误消息应告诉代理如何修复,而不只报告失败。
## 6. 发布门禁
发布候选必须满足:
- [ ] 格式、lint、JVM 测试、UI 测试和 release 构建全部通过。
- [ ] 64 卦内容校验与授权清单通过。
- [ ] 飞行模式核心流程通过。
- [ ] AI 安全测试集和故障降级通过;若 AI 未上线则功能关闭且不影响本地流程。
- [ ] 无生产密钥、敏感日志和真实用户内容进入 APK/测试产物。
- [ ] 浅色/深色、小屏/大屏、最大字体、TalkBack、减少动态效果完成抽测。
- [ ] 隐私政策和应用内数据说明与实际网络行为一致。
- [ ] 数据库迁移、备份策略和删除行为已验证。
- [ ] 已知阻塞缺陷为 0,非阻塞缺陷有记录和责任人。
## 7. 完成定义(Definition of Done)
一个任务只有在以下条件全部满足时才算完成:
1. 关联明确的需求或缺陷编号。
2. 实现遵守领域、架构、UX 和 AI 边界。
3. 新行为有自动化测试,缺陷有回归测试。
4. 执行了与风险相称的验证命令并记录结果。
5. 失败不是通过跳过测试、降低断言或吞异常来“解决”。
6. 用户可见行为或契约变化已经同步文档。
7. 没有引入秘密、未授权内容和敏感测试数据。
8. 交付说明列出变更、验证证据、剩余风险和未执行项。
## 8. 验证报告模板
```markdown
### 验证
- 需求:FR-C-004, FR-C-006
- 已运行:`.\gradlew.bat testDebugUnitTest`
- 结果:通过,N tests
- 未运行:`connectedDebugAndroidTest`(原因:无可用模拟器)
- 人工检查:输入 9,8,8,8,8,8,得到复 24 → 坤 2,初爻动
- 剩余风险:无 / 明确列出
```
不得把未运行写成“应当通过”。