2026-08-04 17:09:52 +08:00
|
|
|
|
# 质量门禁与验证策略
|
|
|
|
|
|
|
2026-08-07 18:00:38 +08:00
|
|
|
|
> 状态:Android 本地门禁已启用;设备门禁在授权真机存在时单独执行
|
2026-08-04 17:09:52 +08:00
|
|
|
|
> 原则:完成必须有可重复证据,不能以“代码看起来正确”代替验证
|
|
|
|
|
|
|
|
|
|
|
|
## 1. 反馈循环
|
|
|
|
|
|
|
|
|
|
|
|
每个实现任务遵循:
|
|
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
|
需求编号 → 最小实现 → 就近测试 → 全量静态/单元检查 → 设备验证 → 文档同步
|
|
|
|
|
|
↑ ↓
|
|
|
|
|
|
└──── 失败归因与修复 ────┘
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
同类失败第二次出现时,应更新[失败记忆](failure-memory.md);适合机械检查的规则必须转成测试、lint 或脚本。
|
|
|
|
|
|
|
|
|
|
|
|
## 2. 预期本地命令
|
|
|
|
|
|
|
2026-08-04 23:28:10 +08:00
|
|
|
|
当前可重复的 Windows 快速门禁:
|
|
|
|
|
|
|
|
|
|
|
|
```powershell
|
|
|
|
|
|
.\gradlew.bat spotlessCheck --offline
|
2026-08-07 18:00:38 +08:00
|
|
|
|
.\gradlew.bat :app:testDebugUnitTest --offline
|
2026-08-04 23:28:10 +08:00
|
|
|
|
.\gradlew.bat verifyContentContract --offline
|
2026-08-07 18:00:38 +08:00
|
|
|
|
.\gradlew.bat verifyLocal
|
2026-08-04 23:28:10 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-08-19 10:58:09 +08:00
|
|
|
|
`verifyLocal` 聚合无依赖格式检查、领域穷举测试、内容 repository 测试、历史编解码测试、问题校验测试、Android lint、debug APK、已解析 Android 调试/单测/仪器测试依赖许可证、domain 依赖边界、内容契约与负向夹具、文档链接、高置信 secret scan、原型 JavaScript 语法检查,以及本机备份排除/无 INTERNET 权限检查。CI 执行同一个聚合任务。首次解析 Android 依赖时不能强制 `--offline`;缓存完成后可用离线模式复核。
|
2026-08-04 23:28:10 +08:00
|
|
|
|
|
2026-08-07 18:00:38 +08:00
|
|
|
|
授权真机存在时,Windows 环境还必须执行:
|
2026-08-04 17:09:52 +08:00
|
|
|
|
|
|
|
|
|
|
```powershell
|
|
|
|
|
|
.\gradlew.bat spotlessCheck
|
|
|
|
|
|
.\gradlew.bat connectedDebugAndroidTest
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2026-08-08 09:19:40 +08:00
|
|
|
|
若本机存在两个不兼容的 ADB server,可在只保留一个 server 的前提下使用等价的可重复入口:
|
|
|
|
|
|
|
|
|
|
|
|
```powershell
|
|
|
|
|
|
.\scripts\run-connected-tests.ps1 -AdbPath <能够稳定识别设备的 adb.exe>
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
该脚本重新构建主/测试 APK、检查授权状态、覆盖安装两者并直接调用同一个 `AndroidJUnitRunner`;失败、零测试或缺少 `OK` 结果都会使脚本失败。若采用不同格式化插件,命令可以调整,但必须在本文件和 CI 同步更新。设备测试继续与环境独立的 `verifyLocal` 分开;`verifyLocal` 通过证明 APK 已构建,但不等于真机测试已经通过。
|
2026-08-04 17:09:52 +08:00
|
|
|
|
|
|
|
|
|
|
## 3. 测试层次
|
|
|
|
|
|
|
2026-08-04 17:54:15 +08:00
|
|
|
|
### 3.0 原型验证(P-1 阻塞视觉确认)
|
|
|
|
|
|
|
2026-08-04 23:00:05 +08:00
|
|
|
|
当前 v0.3 原型已经同步 ADR-012;以下门禁既覆盖核心起卦流程,也覆盖默认本机自动保存策略。
|
|
|
|
|
|
|
2026-08-04 17:54:15 +08:00
|
|
|
|
- `node --check prototype/app.js` 无语法错误。
|
|
|
|
|
|
- `node --check prototype/capture.mjs` 无语法错误。
|
|
|
|
|
|
- `git diff --check` 无空白错误。
|
|
|
|
|
|
- 本地服务运行时,`node prototype\capture.mjs` 退出码为 0。
|
2026-08-04 23:00:05 +08:00
|
|
|
|
- Chromium 360 × 792 走通首页、问题输入、六次录入、结果、解释选择和问卦簿。
|
2026-08-04 17:54:15 +08:00
|
|
|
|
- `9,8,8,8,8,8` 显示复 24 → 坤 2、初爻动;全 7 显示乾 1、无动爻且无之卦。
|
2026-08-04 23:00:05 +08:00
|
|
|
|
- 十八个状态均有可复现截图,包括回访首页/空态、历史列表/空态/详情、保存设置开/关、自动保存/本次未保存、删除和清空确认。
|
|
|
|
|
|
- 回访首页只有一个开始主操作,不出现底部导航或未上线功能占位。
|
|
|
|
|
|
- 首页持续显示本机保存/AI 发送边界;四个保存设置默认开启,总开关关闭后内容开关保留值并停用。
|
|
|
|
|
|
- 完成起卦显示自动保存状态;当次不保存、重新保存、解释关联和清空全部均可复现,删除前显示范围并再次确认。
|
|
|
|
|
|
- 375×812、430×932 和 792×360 无水平溢出;减少动态效果媒体偏好生效。
|
2026-08-04 17:54:15 +08:00
|
|
|
|
- 浏览器控制台无应用错误;页面不发起外部请求;AI 状态明确标为本地模拟。
|
|
|
|
|
|
|
2026-08-04 23:00:05 +08:00
|
|
|
|
自动化审计必须同时断言:以上保存、设置、历史和删除动作产生的外部请求为 0,且 AI 同意门仍须用户单独勾选。
|
|
|
|
|
|
|
2026-08-04 17:54:15 +08:00
|
|
|
|
原型通过只表示流程可供评审,不替代纯 Kotlin 领域测试、Compose UI 测试或真机无障碍检查。
|
|
|
|
|
|
|
2026-08-04 17:09:52 +08:00
|
|
|
|
### 3.1 纯 JVM 领域测试(最快,阻塞合并)
|
|
|
|
|
|
|
|
|
|
|
|
- 三枚铜币 8 种排列映射。
|
|
|
|
|
|
- 六爻 4,096 种组合不变量。
|
|
|
|
|
|
- 64 卦模式映射唯一性。
|
|
|
|
|
|
- bottom-up 顺序和显示适配。
|
|
|
|
|
|
- `CastResult` 序列化往返。
|
|
|
|
|
|
- 本地内容 schema 与完整性。
|
|
|
|
|
|
- 本地解释模板选择。
|
|
|
|
|
|
- AI DTO schema、长度和纯文本校验。
|
|
|
|
|
|
|
|
|
|
|
|
### 3.2 ViewModel/Repository 测试(阻塞合并)
|
|
|
|
|
|
|
|
|
|
|
|
- 投币状态机、返回修改和第六次封印。
|
|
|
|
|
|
- SavedState 恢复。
|
|
|
|
|
|
- 只在用户点击且同意后调用 AI。
|
|
|
|
|
|
- 并发点击、取消和超时不重复提交。
|
|
|
|
|
|
- Room 保存/读取一致性。
|
2026-08-04 23:00:05 +08:00
|
|
|
|
- `autoSaveHistory`、问题、解读和行动四个设置的默认值均为 `true`,且总开关关闭时不自动写入。
|
|
|
|
|
|
- 第六爻锁定只创建一个 session,未完成草稿创建零条;总开关关闭时“保存本次”仍能创建一条。
|
|
|
|
|
|
- 问题、解读和行动内容开关的组合写入准确;当次不保存会删除已自动创建的 session,且不改变全局设置。
|
|
|
|
|
|
- 随后产生的本地/AI 解读关联到同一 session;重新解读不会静默覆盖旧版本。
|
|
|
|
|
|
- 自动保存开启、读取历史或切换保存设置时,AI gateway 收到零次调用;AI 同意状态不被保存设置改变。
|
|
|
|
|
|
- “最近一次”查询随插入/删除更新,且不复制敏感正文。
|
|
|
|
|
|
- 单条删除、清空全部与 session → explanation/action 的级联行为。
|
|
|
|
|
|
- backup/data-extraction 配置测试确认 Room 数据库及 `-wal`、`-shm` 辅助文件不在系统备份或设备迁移范围。
|
2026-08-04 17:09:52 +08:00
|
|
|
|
|
|
|
|
|
|
测试优先使用接口的 fake 实现,不依赖真实网络和实时模型。
|
|
|
|
|
|
|
|
|
|
|
|
### 3.3 Compose UI 测试(阻塞发布)
|
|
|
|
|
|
|
|
|
|
|
|
- 首次说明与方法约定可达。
|
|
|
|
|
|
- 六轮录入的进度、按钮启用状态和错误恢复。
|
|
|
|
|
|
- 结果页本卦/之卦/动爻语义。
|
|
|
|
|
|
- AI 同意、加载、失败、本地降级。
|
2026-08-04 23:00:05 +08:00
|
|
|
|
- 回访首页、最近一次、问卦簿列表/空态/详情和删除确认。
|
|
|
|
|
|
- 首页本机保存/AI 发送说明和设置入口始终可达。
|
|
|
|
|
|
- 保存设置默认开启、总开关联动停用、结果页自动保存状态、当次不保存/保存本次和解释关联反馈。
|
|
|
|
|
|
- 清空全部的危险操作样式、范围说明和二次确认。
|
2026-08-04 17:09:52 +08:00
|
|
|
|
- 最大字体下关键操作可到达。
|
|
|
|
|
|
- TalkBack 语义、焦点顺序和触控目标。
|
|
|
|
|
|
- 旋转/横屏/大屏布局。
|
|
|
|
|
|
|
|
|
|
|
|
### 3.4 端到端与人工验收(阻塞发布)
|
|
|
|
|
|
|
|
|
|
|
|
- 飞行模式走完整核心流程。
|
|
|
|
|
|
- 真机上检查输入法、返回手势、深浅主题和触觉。
|
|
|
|
|
|
- 使用已知六爻夹具人工核对卦象绘制和文本。
|
|
|
|
|
|
- 后端 staging 环境验证同意、超时、限流、非法响应和安全分支。
|
|
|
|
|
|
- 验证安装包不包含生产密钥和未授权内容。
|
2026-08-04 23:00:05 +08:00
|
|
|
|
- 从系统备份/设备迁移恢复后验证问卦簿为空,且设置页未暗示历史已经云端备份。
|
2026-08-04 17:09:52 +08:00
|
|
|
|
|
|
|
|
|
|
## 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 + 安全用例集 | 安全/产品审核 |
|
2026-08-04 23:00:05 +08:00
|
|
|
|
| FR-H-001~008 | 保存策略、Room 事务/版本、删除、备份排除、零网络调用测试 | 首页告知、设置、当次退出与删除体验 |
|
2026-08-04 17:09:52 +08:00
|
|
|
|
| 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。
|
2026-08-04 23:00:05 +08:00
|
|
|
|
- backup/data-extraction 配置不得包含历史 Room 数据库或其辅助文件。
|
2026-08-04 17:09:52 +08:00
|
|
|
|
- 内容校验任务验证 64 卦、384 条爻辞、唯一模式、来源和许可证字段。
|
|
|
|
|
|
- 文档链接和需求编号无悬空引用。
|
|
|
|
|
|
|
|
|
|
|
|
可以使用现有静态工具、架构测试库或小型自定义 Gradle 任务;具体选型写入[决策记录](decisions.md)。规则的错误消息应告诉代理如何修复,而不只报告失败。
|
|
|
|
|
|
|
2026-08-04 23:28:10 +08:00
|
|
|
|
当前由无外部依赖的 Node 脚本与 Gradle 任务执行上述已落地规则,见 ADR-013。引入 Android 源码后应扩展同一入口,不应建立一套互不相干的新命令。
|
|
|
|
|
|
|
2026-08-04 17:09:52 +08:00
|
|
|
|
## 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,初爻动
|
|
|
|
|
|
- 剩余风险:无 / 明确列出
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
不得把未运行写成“应当通过”。
|