# 测试规约与回归门禁 **文档状态**:当前测试事实源。 **适用范围**:hyb-oa MVP 首轮开发 A3-A8,以及后续所有非微小改动。 **路线口径**:WFOC/DBWFOC/WFDG/WDRG/WEGOV1 后,HR/考勤员工日常审批优先复用企业微信成熟能力,OA 做自建留存、按域镜像、人工接管、恢复回写、财务闭环和审计中台;报销、采购、合同、项目、PDF OCR、付款批次、AP 台账、代账交接和高敏附件继续由 OA 主办;企业微信只做脱敏消息和 OA deeplink;飞书不进入当前路线。后续企微/OA 运行时迁移前必须先读 [企微优先开发路线图](./企微优先开发路线图.md),再做对应 POC。WEGOV1 后,WAPC2/WCBK1 不能直接进入 `wecom_attendance_approval_mirror_v1`,必须先完成 WACP3、WREAD1、WADM1 和 WARCH1;WCBK1 已完成真实 URL 验证和事件确认;WPROC2 后先跑 `check-process-contract` process gate;缺配置或权限时记录 `NEEDS_CONFIG` 或 `SKIP/BLOCKED_BY_EXTERNAL_CONFIG`,不得伪造成通过。 本文回答“什么时候测试、测什么、怎么判定通过、怎么记录跳过”。具体业务验收仍以主 PRD、模块规约和最新 Issue CSV 为准。 ## 1. 基本原则 - 测试不是 A8 才开始;每个 Issue 完成开发后必须立即按 `Test_Method` 验证。 - A8 是总回归和试运行门禁,用来证明 A2-A7 组合后仍然可用。 - 自动化优先,自动化无法覆盖时必须写清人工步骤、执行人、环境和结论。 - 测试失败不得假通过;必须先归类为代码问题、测试桩问题、环境问题、数据问题或人工配置问题。 - 涉及公网、企业微信真机、真实 OCR、真实凭据时,只能在条件真实可用后给通过结论;缺配置必须标 `SKIP`。 - 企微审批类测试默认禁止自审;自动化样件必须预检申请人和审批人不是同一 OA 员工、不是同一企微 userid。 ## 2. 测试分层 | 层级 | 目标 | 典型手段 | 通过口径 | | --- | --- | --- | --- | | 静态检查 | 证明代码和配置可解析 | `prisma:validate`、`node --check`、`typecheck`、`build`、`git diff --check` | 命令退出码为 0 | | 单元测试 | 证明局部规则正确 | Vitest route/service/unit tests | 相关用例通过,新增规则有覆盖 | | 脚本回归 | 证明后端业务链路可跑通 | `regression-workflow-actions.sh`、`regression-dedup.sh`、`regression-ocr.sh`、`regression-all.sh` | 脚本成功,失败项可追溯 | | E2E | 证明真实页面流程可用 | Playwright PC、mobile、WeCom UA | 主流程完成,页面状态和接口状态一致 | | 视觉验证 | 证明页面可用且不割裂 | Playwright 截图、DOM 指标、人工审查 | 无桌面页误入手机、无明显遮挡和溢出 | | 真机 / 公网 smoke | 证明部署环境可用 | `/ready`、前端资源、企业微信真机、真实 OCR | 真实条件可用且记录证据;缺条件标 `SKIP` | | 人工验收 | 证明业务角色认可 | 员工、审批人、财务、管理员按清单操作 | 验收人确认或记录遗留问题 | ## 3. Issue 内测试时机 | 时机 | 必做动作 | | --- | --- | | 开发前 | 确认 Issue CSV 已写清 `Acceptance`、`Test_Method`、依赖和回滚说明 | | 后端改完 | 跑 Prisma 校验、相关 `node --check`、相关单测或回归脚本 | | 前端改完 | 跑 `typecheck`、`build`,涉及页面时跑相关 Playwright | | UI 或入口改完 | 做 PC、移动或企业微信 UA 视觉验证 | | Review 前 | 确认 diff 只包含当前 Issue 范围,失败测试已修复或明确阻塞 | | 回填 DONE 前 | `Test_Method` 已执行并通过,或有明确 SKIP 证据 | | Commit 前 | `git diff --check` 通过,Issue 状态和 Notes 已反映真实结果 | `Dev_Status=DONE` 表示开发完成且基础检查通过;`Review1_Status=DONE` 表示自查或 review 无阻断;`Regression_Status=DONE` 表示业务流程级验证通过或明确 SKIP。 ### 3.1 企微工程化测试门禁 WPROC1 后,企微 HR/考勤相关 Issue 在测试层面同步执行三层门禁: | 门禁 | 测试要求 | | --- | --- | | 路线门禁 | 测试前核对路线图,确认没有跳过 WAPC2F、WCBK1、WEGOV1、WACP3、WREAD1、WADM1、WARCH1 等前置阶段。 | | 能力门禁 | runner 必须输出真实 `PASS`、`NEEDS_CONFIG` 或 `SKIP/BLOCKED_BY_EXTERNAL_CONFIG`,不能把缺 Secret、权限、可信 IP、模板、回调或可见范围写成通过。 | | 实现门禁 | Issue CSV、静态检查、单测、回归、公网验证、状态回填和中文提交必须按 `Test_Method` 闭环。 | WPROC2 把上述要求固化为自动化 process gate: - 基线门禁:`node scripts/qa/check-process-contract.mjs --baseline`,已接入 `scripts/check-minimal.sh`。 - 合同门禁:`node scripts/qa/check-process-contract.mjs --issue --profile --json`。 - WAPC2F 必须使用 `wecom-approval-fixture` profile;后续企微高风险合同至少使用 `wecom` profile。 Definition of Ready: - Issue CSV 已写清主流程、异常流程、权限、外部配置和脱敏报告边界。 - 已明确 API、Secret、可信 IP、模板、回调、测试账号、申请人、审批人和自审校验。 - live 写入必须有显式 CLI 参数和环境开关;默认 dry-run 或只读。 Definition of Done: - `Test_Method` 全部执行并记录实际结果。 - 自动化能覆盖的样件生成、复跑、只读拉取、脱敏检查和错误分类已自动化执行。 - 人工只保留批准、密钥/回调配置、企微后台不可 API 化配置、真机确认和风险拍板。 - 若面向公网或企微可测,必须有 `/ready`、runtime smoke、public bundle scan 或对应 live runner 证据。 高风险企微能力的 POC 顺序固定为:WAPC2F 自动样件 -> WAPC2FLIVE live 创建与 WAPC2 自动复跑 -> WCBK1 回调只读 POC -> WEGOV1 企微主办治理与自建留存路线修正 -> WACP3/WACP3R 补偿拉取 POC -> WREAD1 审批可读性与误审批防护门禁 -> WADM1 自建留存/镜像数据模型设计 -> WARCH1 最小自建历史留存实现 -> `wecom_attendance_approval_mirror_v1`。当前 WAPC2FLIVE、WCBK1 和 WACP3R 均已完成,后续不得跳过真机可读性、自建留存模型和最小历史留存门禁。真实回调必须先证明验签、解密、幂等和重复投递;补偿拉取必须先证明按时间窗口拿到审批单号并可拉详情;可读性门禁必须确认审批消息、列表、详情页和快捷同意/驳回误操作风险;镜像实现前必须先有字段、状态机、幂等键、索引和隐私保留边界设计。 WEGOV1 后的企业微信测试环境口径:不假设自建应用有完整隔离 sandbox。自动化优先覆盖 API、回调、补偿拉取、脱敏报告和 OA 留存校验;人工只确认后台不可 API 化配置、真机收到/点击、审批详情是否看得清、正式写入和应急风险拍板。 ## 4. MVP 首轮测试矩阵 | Issue | 自动化测试 | 视觉 / 入口验证 | 备注 | | --- | --- | --- | --- | | A3 报销发票 OCR 主链路 | `regression-dedup.sh`、`regression-ocr.sh`、报销主流程 E2E、发票 OCR E2E | PC 报销详情、移动报销、上传/OCR 状态、重复提示、付款/导出入口 | OCR 真实 provider 缺配置时标 `SKIP`,mock 只证明本地链路 | | A4 企业微信入口绑定通知回 OA | wecom auth 单测、notification dispatcher 单测、WeCom 入口 E2E | 登录页、未绑定提示、移动入口、WeCom UA deeplink | 真机企业微信验证留到 A8 | | A5 请假补卡外出加班与考勤口径 | leave route 语法、请假流程 E2E、团队日历 E2E | PC 请假、移动请假、团队状态或日历 | 不接企业微信打卡 API,不重造定位和人脸 | | A6 P1 采购合同项目最小可用 | procurement 回归、采购/项目 E2E、合同台账人工或 E2E | 采购申请、合同台账、项目详情 | 不扩展预算、ERP、AI、复杂招采 | | A7 权限导航与备用模块护栏 | `typecheck`、`build`、权限导航 E2E | 员工、主管、财务、管理员入口对比 | 前端隐藏不能替代服务端权限 | | A8 总回归门禁 | `regression-all.sh`、前端 build、web gates、live smoke env check | PC、移动、企业微信 UA 组合截图 | 未部署不得告知用户可公网或真机测试 | ## 5. 视觉验证规则 涉及 PC、手机或企业微信 WebView 的页面改动,默认补视觉验证。截图建议放在 `output/playwright//`,文件名包含页面、角色和视口。 | 场景 | 视口和入口 | 必查项 | | --- | --- | --- | | PC | 1440x960,普通浏览器 | 导航清晰、主流程入口可见、信息密度合适、无内部码值主展示 | | 手机 | 390x844,普通移动浏览器 | 无桌面宽表、无横向滚动、底部导航不遮挡、按钮可点 | | 企业微信 UA | iPhone + `wxwork` UA | 默认进入 `/mobile`,deeplink 回 OA,未绑定提示可理解 | | 弹窗 / 表单 | PC 和移动至少各一次 | 文字不截断、不遮挡、不会默认弹键盘影响首屏 | 移动端硬性检查: - `scrollWidth <= viewportWidth + 2`。 - 不出现 PC 侧边栏或桌面表格主体验。 - 不把 UUID、内部状态码、技术错误作为主要展示文案。 - 上传、提交、审批、付款等关键按钮状态清楚。 - 异常提示能指导用户下一步操作。 ### 5.1 当前最小回归组合 R7E 前和后续非微小改动至少从以下组合中按风险选择;进入 R7E Go/No-Go 时必须全部覆盖并记录证据: | 类别 | 命令或证据 | 口径 | | --- | --- | --- | | CSV 合同 | `python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py ` | 所有当前 Issue CSV 校验通过 | | 前端基础 | `cd client && npm run typecheck`、`cd client && npm run build` | 类型和构建通过,Vite chunk warning 不单独阻断 | | 设计规则 | `node scripts/qa/check-ui-design-rules.mjs --strict` | 当前 UI 设计规则 0 findings | | MIF7 移动矩阵 | `cd client && npx playwright test tests/e2e/dg7-mobile-information-dedupe.spec.ts --workers=1 --reporter=list` | 首页、进度/审批、通知、三类详情和财务首页通过;公网时设置 `E2E_BASE_URL=https://oa.hyinda.com` | | R6/MUD6/WCM6 移动回归 | `r6-mobile-responsive-system-hotfix`、`r6-mobile-unified-design-rollout`、`r6-wecom-mobile-rendering-hardening` | 旧移动矩阵用于防止信息架构整改破坏基础移动体验 | | 公网匿名 | `/ready`、`check-public-bundle-copy.mjs` | `/ready` 成功且 public bundle findings=0 | | 带凭据 live readiness | `LIVE_SMOKE_BASE_URL=https://oa.hyinda.com QA_ISSUE_ID= bash scripts/qa/run-live-smoke-readiness.sh` | live smoke 和真实 OCR 不含 `SKIP`;pending OCR 可按规则非阻断 `SKIP` | | 核心业务流 | `BUSINESS_FLOW_GROUPS=reimbursement,approval,leave,procurement,governance bash scripts/qa/run-business-flow-gates.sh local` | 工具会话无法稳定承载长组合时,可按相同 groups 分段执行并在报告中引用各分段 PASS 目录 | 门禁分为三类:本地门禁证明代码和 mock/隔离库可用;公网匿名门禁证明部署入口和前端资源可用;带凭据门禁证明真实账号、live smoke 和真实 OCR 可用。三类不得混用,缺哪一类就写清缺口。 QAOPS8 之后,当前门禁台账按四类读取: | 门禁类别 | 当前用途 | 当前状态口径 | | --- | --- | --- | | 本地门禁 | 代码、mock、隔离库、构建和 Playwright 基线 | 可由自动化证明,但不代表公网或真机通过 | | 公网匿名 | `/ready`、public bundle、匿名页面和公网移动矩阵 | 证明部署入口和前端资源可用,不读取凭据 | | 带凭据 | live smoke、真实 OCR、角色账号和受保护接口 | 缺凭据、样票或授权时只能记录 `SKIP` | | 企业微信真机 | 入口、绑定、免登、deeplink、WebView 和代表设备体验 | 必须有人工或代表设备证据,自动化 UA 不能替代 | ### 5.2 历史专项分类 | 专项 | 当前归类 | 处理规则 | | --- | --- | --- | | R108/R109 移动视觉专项 | 历史证据和待修测试初始化 | 不是当前 R7E 硬门禁;初始化 API 不可用时只能记录 `SKIP`,不得写成视觉通过 | | R6/MUD6/WCM6 移动专项 | 当前移动基础回归 | MIF7/MIF7T 后仍需保持可运行,用于防止基础移动体验回退 | | MIF7/MIF7T 移动整改专项 | 已收口证据和当前矩阵参考 | 作为新移动变更的回归参考,不能替代新增真机验收 | | 其他历史专项 | 历史证据 | 重新进入当前门禁前,必须先更新对应 Issue CSV 的 `Test_Method` 和验收口径 | ## 6. SKIP 规则 只有确实缺少外部条件时才能标 `SKIP`。`SKIP` 不是通过,必须写清原因和后续补测条件。 | 场景 | 可 SKIP 条件 | 必须记录 | | --- | --- | --- | | 企业微信真机 | 缺 CorpID、AgentID、可信域名、回调域名、可见范围或手机企业微信账号 | 缺哪个配置、自动化已覆盖哪些、A8 何时补 | | 真实 OCR | 缺腾讯 OCR 凭据、网络或真实样票授权 | 当前 provider、mock 覆盖范围、真实 OCR 补测步骤 | | 公网 smoke | 未部署或公网域名不可用 | 本地验证结果、部署前置条件 | | 生产数据验证 | 无授权、无脱敏样本或存在数据风险 | 不执行原因、需要谁批准 | ## 7. 失败处理 测试失败后先分类,再决定修复方式: | 分类 | 处理方式 | | --- | --- | | 代码问题 | 当前 Issue 内修复并重跑相关测试 | | 测试桩问题 | 修测试夹具或 mock,不能降低真实验收口径 | | 环境问题 | 记录环境差异,必要时重启本地服务或切换隔离测试库 | | 数据问题 | 使用 seed、隔离测试库或清理本轮产生的数据;不得直接重置生产库 | | 人工配置问题 | 记录缺失配置,A8 或部署阶段补测 | 如果失败暴露出超出当前 Issue 的业务缺口,不能顺手扩大实现,应记录到 Notes 或新 Issue。 ## 8. 回填和证据 Issue 状态回填必须基于证据: - `Dev_Status=DONE`:实现完成,静态检查或对应基础测试通过。 - `Review1_Status=DONE`:自查或 review 已确认无阻断风险。 - `Regression_Status=DONE`:流程级测试通过,或按 SKIP 规则记录不可执行原因。 最终回复和 commit 前至少说明: - 改了什么,对应哪个 Issue。 - 跑了哪些命令,结果如何。 - 哪些测试 SKIP,原因是什么。 - 是否部署;未部署时不得引导用户去公网或企业微信真机测试。 ## 9. 与其他文档的关系 - 主 PRD 回答“做什么、为什么、如何验收”。 - 本文回答“如何测试和何时可过门禁”。 - `docs/试运行与自动化验证手册.md` 回答“本地、公网、企业微信、真实 OCR 怎么操作”。 - `docs/开发交付与变更管理规约.md` 回答“如何 review、提交和交付变更”。