first commit

This commit is contained in:
2026-06-25 06:25:30 +08:00
commit 561af47817
46 changed files with 2719 additions and 0 deletions
@@ -0,0 +1,88 @@
# 02 · 测试与验收计划
> 唯一判据:**现有 H5 零改动运行**,且行为与《契约规范》§8/§9/§11 完全一致。
## 1. 测试层次
| 层次 | 对象 | 手段 | 何时 |
|---|---|---|---|
| **单元测试** | 纯逻辑:`MessageCodec``HandlerRegistry``VersionResolver``ConfigManager` 解析、各 DTO 序列化 | ArkTS 单测 + `FakeWebController` | 随开发,CI 强制 |
| **桥协议测试** | `BridgeController` 全路径 | FakeWebController 模拟 H5 收发 | M1 |
| **集成测试** | 容器 + 启动 + 资源 + 配置 | 真机/模拟器 | M2 起 |
| **契约一致性测试** | 全 44 入站 + 全出站 handler | 真机 + 测试 H5 探针 | M3 起每周回归 |
| **端到端(E2E** | 真实大厅 H5 + 子游戏 + 活动页 | 真机手测 + 录屏 | M3/M4 |
| **性能测试** | 冷启动、子游戏切换、内存 | DevEco Profiler / hilog 打点 | M5 |
| **安全测试** | 加固清单 | 人工审查 + 工具 | M5 |
## 2. 关键测试资产
### 2.1 最小回显 H5M1 必备)
一个独立测试页,仅用桥 API
- `registerHandler('echo', (d,cb)=>cb(d))``callHandler('getTime')``callHandler('echo','hi')`
- 验证:H5→原生→回执、原生→H5→回执、启动前积压消息补发、`yy://` 拦截(V1)。
### 2.2 契约探针 H5M3 回归)
一个覆盖**全部 44 入站 handler**的探针页:逐个 `callHandler` 并记录回传,与《契约规范》期望值比对,输出"通过/差异"报告。出站 handler 用 `registerHandler` 全量挂载、记录原生推送。
> 此页是"H5 零改动"的自动化守门员,纳入每周回归。
## 3. 两个阻塞性验证(最高优先,决定技术路线)
| 验证 | 用例 | 通过判据 | 不通过 → 动作 |
|---|---|---|---|
| **V1 `yy://` 拦截**M1, T-M1-07 | 最小 H5 设 `iframe.src='yy://__queue__'`,原生 `onLoadIntercept` 取 URL | 能拿到 `yy://` URL 并拦截、`_fetchQueue` 回执经 `yy://return/` 到达 | 切 `onInterceptRequest`+`WebSchemeHandler`;或改桥 JS 走 `javaScriptProxy.postMessage`[00 §5](./00_总体规划.md) |
| **V2 `file://` 跨域**M2, T-M2-08 | 现有大厅 `index.html``file://` 加载,请求本地 js/css/图片/`app_data.js` | 资源全部正常加载、H5 正常运行 | 启用自定义协议/`onInterceptRequest` 接管本地资源(框架 §7.3 |
> 这两项必须在对应里程碑**作为 Exit Gate 强制通过**。
## 4. 契约一致性核对清单(H5 零改动判据)
### 4.1 桥协议(§2
- [ ] `window.WebViewJavascriptBridge` 注入后 API 与事件 `WebViewJavascriptBridgeReady` 一致
- [ ] `registerHandler`/`callHandler` 双向、回执、`callbackId`/`responseId` 路由正确
- [ ] `_fetchQueue``yy://return/` 回传(非 runJavaScript 返回值)
- [ ] 启动前积压消息在注桥后补发
### 4.2 入站 44 handler(§8)—— 逐条核对名称/参数/同步返回
- [ ] 账号社交:`accreditlogin``friendsSharetypeUrlToptitleDescript``getphoto`
- [ ] 支付:`paybrowser``getGameplay`(**本期桩,验"不报错不卡死"**
- [ ] 设备信息:`getTime``getphonestate``getbattery``getwifiLevel``getnetwork``getcompareCode``getphoneInfo``getmarketname``getothername``getOther`
- [ ] 交互:`orientation``vibrator``repeatvibrator``canclevibrator``gameCopytext``gamepastetext``notification`(空)
- [ ] 摇一摇:`startshake``SwitchShake``stopshake`
- [ ] 定位:`startlocation``getlocationinfo`
- [ ] 音频:`prepareaudio``mediaTypeAudio``srcIsloop``voicePlaying`
- [ ] 扫码/相机/浏览器/网页:`opensaoma``opencamera``browser``OpenurlTitleData``openApplyDownloadpath`
- [ ] 子游戏/房间:`SwitchOverGameData``getGameinstall``createRoom``exitRoom``getVideoinfo``DragViewvideoIsshow`**房间本期桩**
- [ ] 退出/返回:`finsh``backgameData`
### 4.3 出站 handler(§9)—— 逐条核对名称/data 结构/时机
- [ ] `appservice`(1/2)、`setPostUrl``getWebdata``getphoto``sharelogin``sharesuccess``shakeEnd``getBattery``getwifiLevel``getnetwork``getaudiourl`(+`filepath`)、`gameui_play_voice``gameui_stop_voice``getphoneinfo``getVideoinfo`(桩不推)、`PayuserPaytypePaystate`(桩不推)、`getlocationinfo``phonestate``getsaomaData``getcameraaAddress`
- [ ] 名称陷阱:`backgameData-`(带连字符)≠ 入站 `backgameData`
### 4.4 数据结构(§12
- [ ] `sharetypeBean`/`MaplocationInfo`/`phoneInfoBean`/`savephotoURLBean`/`videoinfobean`/`Othervideoinfo`/支付/`sharelogin`/`sharesuccess` 字段名同名同义
### 4.5 启动/资源/容器(§3–§7、§11)
- [ ] 配置键齐全、远程配置分层覆盖、`showmessage` 阻断
- [ ] 资源路径、version.xml 版本比较、zip 下载解压
- [ ] `app_data.js` 全局变量、**加载前注入**
- [ ] 入口 URL`weburl` 空/非空)、`?Launchtype=` 参数
- [ ] 通用网页容器 `settings` 6 法 + 3 直调 + 101 回传
## 5. 里程碑验收 Gate
| 里程碑 | Gate |
|---|---|
| M0 | 工程编译/签名/CI 通过;`contracts` 全量类型对照契约零缺漏 |
| **M1** | 回显 H5 双向通;**V1 通过**;桥单测 ≥80% |
| **M2** | 真机加载大厅 H5、进子游戏;**V2 通过**app_data.js 时序正确 |
| M3 | §4.2/§4.3/§4.4 清单全过;**桩能力不报错不卡死** |
| M4 | §11.3 通用容器一致;活动页/收银台/客服打开回传正常 |
| M5 | 切换 <300ms、冷启动 <2s(基线);安全清单(附录 B)全过;可观测可用 |
| **本期总验收** | 现有大厅 + 全部子游戏 + 网页页面**零改动运行**;§4 全清单通过 |
## 6. 缺陷分级与回归
- **P0**:H5 无法运行/桥不通/崩溃 → 当日修复,阻塞合入。
- **P1**:某 handler 行为不符契约 → 当迭代修复。
- **P2**:性能/体验 → M5 收口。
- 每次合入触发"契约探针 H5"回归,防止已通过的 handler 退化。