# HDLKiosk 测试与验收

> 自动测试证明本地语义，真实 OS/设备/支付验收决定是否生产可用。

## 1. 测试层级

| 层级 | 范围 | 目标 |
| --- | --- | --- |
| L1 | Contract、纯函数、normalizer、guard | 输入边界和映射确定 |
| L2 | Kernel Coordinator/Actor、Ingress、Scale Runtime | 并发、时序和危险状态 |
| L3 | Screen/View Model/Controller | 语义事件、禁用态、错误展示 |
| L4 | Fake Host 纵向流程 | 三入口正常与异常路径 |
| L5 | BigSale Adapter contract | raw Context、callback、capability 和 late bridge |
| L6 | 真实 BigSale/OS/设备/支付 | 生产事实和长时间稳定性 |

L1–L5 通过不能替代 L6。

## 2. 每次变更的最小验证

- 修改 Contract/Projection：对应纯函数和 Adapter contract；
- 修改 Operation：成功、失败、cancelled、partial、unknown、timeout；
- 修改 Workflow：compiler、definition、actor 和受影响入口纵向测试；
- 修改设备：dedupe、背压、lifecycle、自动入口和真实设备；
- 修改 Checkout：安全集成测试和刷新/重启人工测试；
- 修改 UI：View Model、语义事件、禁用/错误态和目标分辨率人工验收。

## 3. 黄金路径

### Quick

Guest/Member → 主商品称重/options → Catalog → 堂食/外带 → Cart Overlay 复核/卡券 → Card/Cash → Payment 内成功展示 → 10 秒 Reset。登录或 Skip 后，在堂食/外带页点击 Back 应先展示结束订单确认；确认后返回 Entry，取消后留在当前页，不得再次停留在 Identity 或回弹。

### Barcode

有效扫码自动加购 → Catalog；缺主商品且选择添加时 → 主商品称重/options → Next/OS 加购成功 → Catalog；随后通过 Fulfillment 和 Cart Overlay 复核/卡券 → Payment 内成功展示。Quick 返回 Entry 后再次扫码也必须能启动 Barcode。

### Scale

有效正重自动进入稳定称重/options → Next/OS 加购成功 → Catalog → Fulfillment → Cart Overlay 复核/卡券 → Payment 内成功展示。

三条路径都要覆盖 Shell 中途登录和最新 Summary 结账。

## 4. 必测异常矩阵

| 领域 | 场景 |
| --- | --- |
| Session | ensure 失败、Host 替换、epoch 迟到结果、reset 不完整 |
| Cart | 重复点击、写后未观察、Summary missing、价格变化、并发会员登录 |
| Barcode | 重复帧、无 eventId、notFound、requiresSelection、队列溢出 |
| Scale | 断连、重连、抖动、过期、负重、超载、回零、持续压秤 |
| OS add flow | 顾客取消、失败、超时、返回不明确、写后不一致 |
| Checkout | cart 变化、token 过期、零元、失败、取消、timeout、callback 丢失 |
| 刷新处置 | 有 cart、payment pending/unknown、OS 清理空壳 |
| Privacy | reset 后会员、券和上一单 UI 不残留 |

## 5. Adapter 重点契约

- retail Catalog 不发生二次 load；
- 称重主商品 load/add 均调用 `queryProducts({ includeIds })`，无结果或 capability 缺失时不生成 mock；
- `queryProducts` capability 缺失或主商品 ID 未配置时，三个入口均不可启动；Scanner 自身可用不等于 Barcode 业务入口可用；
- 查询所得 ProductData、option 和称重单位映射正确；
- Customer/Fulfillment/主商品加购的写后事实可观察；
- `pending/payment_processing/payment_pending/paid` 映射符合当前 OS 语义；
- `paid + 无 orderId + 空 cart` 为已清理空壳；其他不完整 paid 继续 unknown；
- callback 模糊、字段缺失、同步抛错和迟到结果 fail-closed；
- bridge/source 晚到不替换 Host 或活跃 Workflow。

## 6. 真实环境验收

生产候选至少完成：

- 三入口真实 OS 下单闭环；
- 真实扫码器和电子秤全矩阵；
- 正常金额与零元支付；
- Card 成功/失败/取消/超时/unknown；
- 支付成功取餐码/生成中状态、10 秒自动返回和手动返回；
- 支付页重新开始订单的二次确认，以及 pending/unknown 下的禁用门禁；
- Cash 和员工处置；
- 刷新、WebView 重启、应用挂起、断网和断电；
- 100 次以上连续开单/reset；
- 大目录滚动、内存、订阅和 timer；
- 目标分辨率、触摸、软键盘、多语言和可达性；
- 会员、优惠、pickup、积分和隐私清理。

## 7. Definition of Done

一项能力只有同时满足以下条件才完成：

- 业务行为和失败边界明确；
- Contract/Operation/Projection/Screen 职责没有越层；
- 自动测试覆盖关键分支；
- 对应 BigSale Adapter contract 通过；
- 真实 OS 或设备人工验收通过；
- 临时开关和残余风险已登记；
- 文档与代码同步。

没有真实 Host 注入或实机验收的能力只能标记“本地切片完成”，不能标记“生产完成”。

## 8. 本工作区验证规则

- 不使用 `pnpm` 或 `npm` 运行 material webpack build；
- 优先使用定向 Vitest、轻量 TypeScript/语法检查和依赖边界测试；
- genuinely 需要 material build 时使用全局 `xbuild`；
- 不为通过测试覆盖用户无关手动变更；
- 测试因工作区依赖或用户文件缺失不能启动时，记录启动阻塞与已完成的替代检查。

## 9. 验收记录方式

`实施进度.md` 只记录最近有意义的验证摘要，不累积每次命令流水。单项交付记录：

```text
范围：
业务结果：
安全不变量：
自动验证：
真实 OS/设备验收：
临时策略与风险：
```
