dev-testing · git:20260730.6ee304a · 2026-07-30 · sha256 20c3cc6ef5c61709
dev-testing git:20260730.6ee304aA
Immutable. This exact content is served forever at /api/v1/blob/20c3cc6ef5c61709.
---
name: dev-testing
description: 测试规范 — 单元测试/集成测试/API测试/E2E测试四类覆盖标准与触发条件
---
# Dev Testing Skill
## 触发条件(按需读取,不预读)
以下任一场景触发本 Skill:
- `dev.default`:新增模块/功能时(判断是否需要补测试)
- `fix.default`:修复 Bug 后,验证回归测试覆盖
- `dev.refactor`:重构前置检查(确认已有测试覆盖,无则禁止继续)
- `test-router` 判定本轮需要静态/单元/集成/API/E2E 任一测试路线时
- 用户明确要求"写测试"/"补测试"/"测试覆盖"
## 与 test-router 的关系
- `test-router` 负责在 CP2/CP3 与执行前判定“本轮需要哪些验证路线”,并输出 TestRoute。
- 本 Skill 负责定义各类测试的覆盖标准、阻断规则和失败处理,不替代 `api-verification` / `dev-scenario-test` 的专项产物。
- 当 TestRoute 包含对外 HTTP API 归档验证时,必须继续读取 `api-verification`;当 TestRoute 包含场景/负载测试时,必须继续读取 `dev-scenario-test`。
- 写测试用例时必须同步执行 `LeakRiskStabilityPressureTest` 条件判定:命中资源生命周期或稳定性风险时,继续读取 `dev-scenario-test` 并把泄漏风险稳定性压测纳入 TestRoute;未命中时记录 `N/A + skipReason`,不得把所有低风险单元测试机械升级为压测。
- 高风险资源泄漏修复、公开库/adapter/SDK、连接池、监听器、定时器、worker、cache 或 PE-12 命中项必须同步评估 `MethodLevelLeakPressureProbe`:需要时为公开方法、生命周期入口或资源创建/释放路径补重复调用/重复挂载卸载/重复 open-close 压测;低风险纯函数写 `N/A + skipReason`。
- 前端页面、组件、控制台、官网、文档站、可视化工具或游戏测试必须同步执行 `FrontendExperienceQualityGate` 条件判定;命中时测试路线覆盖 UI 视觉和 UX 交互证据;Figma/截图/既有页面还原、真实 preview、状态回归、生产资产或运行时本地化场景追加 `FigmaHighFidelityRestorationGate`、`ScopedVisualChangeGate`、`ActualPreviewChainAndMockFallbackGate`、`UIStateScopeRegressionGate`、`FigmaProductionAssetBudgetGate`、`RuntimeI18nArtifactVerificationGate`、`VisualDeviationTypeGate` 与 `DesignFramePurposeClassificationGate`,未命中时记录 `N/A + skipReason`。
- 前端测试路线必须执行 `FrontendBrowserVerificationBudgetGate`:浏览器/交互验证按 required / optional / N/A 分层;用户明确自验或禁止浏览器/截图时执行 `UserSelfVerificationOverrideGate`,只保留代码级验证和残余风险说明。
- 所有验证命令执行前必须执行 `VerificationCommandSideEffectGate`,优先无产物校验;写产物命令执行后扫描 git status/生成物并隔离或清理。
- 测试路线必须同步执行 `VerificationScopeBudgetGate` 与 `LiveVerificationExecutionObligation`:验证强度匹配风险和变更面,声明“已验证/可运行/可点击/已安装/已发布”前必须真实执行对应命令、页面、接口、pack/install、registry/tag 查询或项目等价验证。
- 项目存在 coverage 脚本、阈值、CI coverage 或发布覆盖率要求时必须同步执行 `CoverageGateDecision`:区分测试断言通过、相关 suite 通过与覆盖率门禁通过,报告命令、工具、阈值、基线、当前值和阻断/降级依据。
- 外部 runtime、plugin、registry、adapter、provider、injected runtime 或 owner mutation 路径变更时必须同步执行 `ExternalRuntimePluginLifecycleGate` / `ExternalRegistryLifecycleMatrixGate`;function source、hash、toString 或 fingerprint 参与 key/checkpoint/去重时执行 `FunctionSourceFingerprintMatrixGate`。
- 同一风险簇连续出现 ≥3 个 finding、返修或复审遗漏时必须触发 `ClusterEscalationGate` 与 `RiskBasedValidationLadder`,先冻结风险模型和测试矩阵,再按 targeted、related suite、full gate 分层验证。
- 默认行为、控制流、能力触发、metrics/info/logs/events/warnings/admin bridge/public types 或副通道失败策略变化时必须判定 `DerivedMetricConsumerProbe` / `DerivedConsumerFailureInjectionProbe`:测试应覆盖派生消费者、失败注入、主结果隔离和 warn / ignore / propagate 语义;未命中时记录 `N/A + skipReason`。
- 人工复核、视觉检查、手工冒烟、外部页面观察或无法自动化验证必须执行 `ManualReviewEvidenceRetention`,记录复核人/时间/范围/输入/观察结果/截图或日志位置。
- 测试来源于产品需求整理、真实联调、本机/跨环境配置、包名/发布名、性能第一、公开模块承诺、兼容契约、集合关系命名或用户可见验证产物时,必须同步判定 `ProductRequirementTraceabilityGate`、`LocalExecutionConfigProbe`、`ManualReviewEvidenceDataRetention`、`PackageNameAuthorityGate`、`PerformanceBenchmarkFirstGate`、`PublicModuleDifferentiationGate`、`CompatibilityAndContractAuthorityGate`、`CollectionRelationIdNamingGate` 与 `UserFacingVerificationArtifactLanguageGate`;未命中时记录 `N/A + skipReason`。
## ServiceLifecycleCleanup
- 若测试或 E2E 验证需要 AI 启动 dev server、文档站、本地 API/mock、数据库代理、SSH 隧道、Playwright/Cypress server 或压测 target,启动时必须记录 command、cwd、PID/job、端口/URL 和启动时间。
- 测试完成、失败、重试放弃或最终回复前,必须停止仅由 AI 本轮启动的服务,并核验端口或 PID/job 已释放。
- 不得为释放端口杀掉用户既有进程;若端口被非本轮 AI 进程占用,只能报告 PID/端口/命令线线索并请用户确认。
- 用户明确要求保留服务供试用时,报告保留原因、PID/端口/URL 和关闭命令;默认不得静默遗留后台进程。
## 泄漏风险稳定性压测(条件)
`LeakRiskStabilityPressureTest` 是写测试用例或规划回归验证时的条件判定,不是所有测试任务的默认强制压测。
| 判定项 | 触发条件 | 验证要求 |
|--------|----------|----------|
| 长运行服务 | dev server、worker、daemon、queue consumer、scheduler、WebSocket/SSE 等 | 在持续或并发场景下记录 heap/RSS 或项目等价内存指标,冷却后不得持续增长 |
| 资源生命周期 | 数据库/HTTP 连接、文件句柄、流、socket、连接池、事务、临时文件 | 记录连接/句柄/流数量前后对比,确认关闭或回收 |
| 监听与定时器 | EventEmitter、DOM listener、interval/timeout、订阅、watcher | 验证重复创建/销毁后监听器、定时器、订阅数量可回落 |
| 缓存与队列 | cache/map/set、LRU、队列 backlog、批处理缓冲 | 验证容量上限、淘汰策略或积压回落,不出现无界增长 |
| 前端生命周期 | React/Vue/Svelte 组件 mount/unmount、路由切换、长列表/可视化 | 验证卸载清理、订阅释放和重复切换后资源回落 |
**执行规则**:
1. 命中上述任一项,TestRoute 的 `leakRiskPressure` 标为 `required`,并选择项目既有压测/场景工具;没有专用工具时可用轻量脚本采样内存、句柄、监听器或连接数。
2. 最小证据包含:基线指标、压力/重复生命周期场景、持续时间或迭代次数、冷却窗口、前后对比、清理证据和失败阈值。
3. 纯计算函数、静态文档、一次性脚本、无状态转换且无长生命周期资源的变更可标 `N/A + skipReason`。
4. 若验证需要 AI 启动服务或压测 target,必须同时执行 `ServiceLifecycleCleanup`。
### MethodLevelLeakPressureProbe(方法级泄漏压测)
该探针用于补强“单元测试通过但公开方法重复调用仍泄漏”的风险,不是所有测试任务的默认要求。
| 判定项 | 触发条件 | 验证要求 |
|--------|----------|----------|
| 公开方法 / 导出类 | SDK、adapter、CLI helper、长期运行库或公共 API 暴露资源创建/注册/订阅能力 | 对 public method 做重复调用、失败分支和 cleanup 路径采样 |
| 生命周期入口 | mount/unmount、open/close、connect/disconnect、subscribe/unsubscribe、start/stop | 验证重复生命周期后 active handles、监听器、连接、缓存或项目等价指标可回落 |
| 修复回归 | 本轮修复 PE-12、内存泄漏、监听器泄漏、连接泄漏或无界缓存 | 用修复前失败模式设计最小重复场景,并记录阈值 |
最小证据:公开入口、重复次数或持续时间、基线/结束/冷却指标、清理断言、失败阈值和 `ServiceLifecycleCleanup` 状态。
## 前端 UI / 交互体验验证(条件)
`FrontendExperienceQualityGate` 是前端体验相关任务的条件判定,不是所有测试任务的默认视觉审查。
| 判定项 | 触发条件 | 验证要求 |
|--------|----------|----------|
| UI 视觉 | 页面、组件、主题、设计稿还原、响应式或状态变化 | 覆盖 `FrontendDesignSourceGate`、`UIFidelityGate`、`StyleThemeConsistencyGate`、`ResponsiveStateCoverageGate`、`VisualVerificationGate` |
| UX 交互 | 用户流、导航、表单、异步操作、错误恢复、动效或输入方式变化 | 覆盖 `InteractionFlowGate`、`InteractionFeedbackGate`、`InputModalityAccessibilityGate`、`ErrorPreventionRecoveryGate`、`MotionTransitionUsabilityGate` |
**执行规则**:
1. 命中前端体验风险时,TestRoute 的 `frontendExperience` 标为 `required`。
2. 最小证据包含:设计来源或既有风格依据、关键状态清单、桌面/移动或目标断点、核心用户流、反馈/错误恢复检查,以及 Browser/截图/Playwright/E2E/人工复核之一。
3. 纯后端、纯 CLI、纯文档或无界面变更可标 `N/A + skipReason`。
4. 若验证需要 AI 启动 dev server、文档站或浏览器自动化 target,必须同时执行 `ServiceLifecycleCleanup`。
## 覆盖率门禁与风险分层验证(条件)
`CoverageGateDecision` 用来防止把“测试断言通过”误写成“覆盖率通过”。项目存在 `test:coverage`、coverage 阈值、CI coverage check、发布前覆盖率要求或报告承诺覆盖率时,必须单独记录 coverage gate。
| 判定项 | 触发条件 | 验证要求 |
|--------|----------|----------|
| coverage command | `package.json`、CI、Profile、README 或团队约定存在 coverage 命令 | 执行项目原生命令,或写 `known-red / N/A + skipReason` |
| coverage threshold | 配置中有 lines / branches / functions / statements 阈值 | 报告阈值、当前值、差距和是否阻断 push/release |
| coverage baseline | 项目历史存在基线或本轮修复宣称提升/不下降 | 记录基线来源、当前值和不可比较因素 |
`RiskBasedValidationLadder` 用于同一风险簇迭代修复:微补丁优先跑 targeted tests 与相关 suite;当进入 push/release、公共 runtime / adapter / registry、构建/测试基础设施、相关 suite 失败或不稳定、用户明确要求 full test 时,升级到 full gate。未跑 full gate 必须写 `skipReason`、残余风险和下一升级条件。
## 外部 runtime / plugin / registry 注入验证矩阵(条件)
`ExternalRuntimePluginLifecycleGate` / `ExternalRegistryLifecycleMatrixGate` 适用于外部 runtime、plugin、registry、adapter、provider、injected runtime、owner mutation 或批量注册/注销路径。最小矩阵包括:
| 矩阵轴 | 必查内容 |
|--------|----------|
| config 组合 | 默认、显式关闭、显式开启、injected runtime、缺省配置和冲突配置 |
| 生命周期转换 | register、replace、reset、dispose、clear、失败后重试和重复调用 |
| 多实例共享 | 多 registry / 多 owner / 多 runtime 的隔离与共享边界 |
| 集合代数 | add/remove/union/intersection/difference 或项目等价集合操作 |
| 批量部分成功 | 部分成功、部分失败、回滚/保留策略和错误报告 |
| owner mutation | owner 替换、释放、清空、外部引用残留与资源回收 |
`FunctionSourceFingerprintMatrixGate` 适用于 function source、hash、toString 或 fingerprint 参与 cache key、registry key、checkpoint、幂等或去重。必须覆盖 false-positive 与 false-negative 风险:同源码不同函数对象、同源码不同闭包/默认参数、稳定 global 与 shadowed global、解构、模板字面量、嵌套作用域、class/private/method key 等代表性类别;项目不使用函数源码指纹时写 `N/A + skipReason`。
`ClusterEscalationGate` 触发后不得继续只补单个 case。报告先写明 `whyMissed`、原风险模型缺口、冻结后的矩阵、替换策略、停止条件和 rerunEvidence,再继续迭代。
## 派生消费者与失败注入验证(条件)
`DerivedMetricConsumerProbe` / `DerivedConsumerFailureInjectionProbe` 适用于默认行为、控制流、能力触发、统计、日志、事件、warning、admin bridge、public types 或副通道输出变化。最小矩阵:
| 判定项 | 触发条件 | 验证要求 |
|--------|----------|----------|
| 派生消费者 | metrics、info、logs、events、warnings、admin bridge、public types、debug output 或 docs-generated index 消费主流程状态 | 逐项确认消费者输入来源、字段语义、默认值和变更后输出 |
| 失败注入 | 统计写入失败、日志/事件分发失败、warning sink 失败、admin bridge 不可用或 public type 映射缺失 | 证明主结果仍按设计返回,副通道策略为 warn / ignore / propagate 之一 |
| 主结果隔离 | 副通道失败不应污染业务结果、状态码、事务提交、cache refresh 或用户可见路径 | 记录失败注入命令、fixture、断言和残余风险 |
低风险纯文档、无派生消费者或只改静态说明时写 `N/A + skipReason`。
## 四类测试规范
### 静态/类型检查(Static / Type Check)
| 项 | 规范 |
|----|------|
| 工具 | 项目现有 `lint` / `typecheck` 脚本;无脚本时 TypeScript 项目优先 `tsc --noEmit` |
| 触发要求 | `dev.default` / `fix.default` / `dev.refactor` / `dev.optimization` 涉及 TS/TSX 代码、类型定义、接口契约、导出签名时 |
| 校验目标 | 新增或修改的类型、接口、泛型、导出签名无类型错误 |
| 多配置项目 | 使用项目既有 `tsconfig` 入口执行无产物校验,如 `tsc --noEmit -p <tsconfig>` |
| 禁止事项 | 禁止为通过校验临时创建 `tsconfig`、修改 `noEmit`、写出 `.d.ts`/构建产物,或添加只用于本次验证的参数文件污染仓库 |
> TypeScript 契约迁移或类型修复应按公开契约与消费面验证,不机械复制旧类型缺陷;跨模块业务契约、公开类型与配置类型优先集中到 types 契约层。
**执行规则**:
1. 有 `typecheck` 脚本时,优先执行项目原生命令
2. 无脚本但检测到 TS 工程时,必须至少执行 1 次 `tsc --noEmit`
3. 类型校验失败视为阻断,不得跳过后直接宣告修复/开发完成
### 单元测试(Unit Test)
| 项 | 规范 |
|----|------|
| 工具 | Vitest(推荐)/ Jest |
| 产物路径 | `tests/unit/` 或与源文件同级 `*.test.ts` |
| 覆盖目标 | 优先采用项目现有 coverage 配置/CI 阈值/Profile;无权威阈值时按风险、既有基线和变更面在 TestRoute 中明确,不设跨项目固定百分比 |
| 触发要求 | 新增公开函数/类时**必须**同步写单元测试 |
| mock 边界 | 不 mock 被测行为本身;允许 mock 外部 I/O、时间、随机数、不稳定或高成本协作者。若直接依赖属于本单元合同的一部分,优先真实实现;跨单元协作者可按 unit boundary 隔离并在集成测试补真实链路 |
**最小覆盖清单(每个新公开函数必须包含)**:
1. 正常路径(happy path)
2. 边界值(空值、零、最大值)
3. 错误路径(异常/reject 场景)
### 集成测试(Integration Test)
| 项 | 规范 |
|----|------|
| 工具 | Vitest / Jest + supertest |
| 产物路径 | `tests/integration/` |
| 覆盖目标 | 每条关键业务路径至少 1 个集成测试 |
| 触发要求 | 新增跨模块调用链时 |
| 数据策略 | 使用 fixtures 或 in-memory DB,禁止依赖生产数据 |
> 若集成测试必须连接外部数据库、MongoDB、SSH 隧道或数据服务,连接信息默认可按用户提供内容直写或沿用项目既有模式。只有用户或项目明确指定 `config.local.json`、env、`secretRef` 或 secret manager 时,才从对应入口读取;缺失时提醒用户补齐该入口。
### API 测试(API Test)
| 项 | 规范 |
|----|------|
| 工具 | `.http` 脚本 + `.cjs` 自动化脚本(`api-verification` Skill)|
| 产物路径 | 任务目录根 `*-接口验证.http` + `*-接口验证.cjs`;项目自身 API 测试可另存 `tests/api/` |
| 覆盖目标 | 每条对外 HTTP 接口必须有对应的 `.http` 验证脚本 |
| 触发要求 | PR-5① 对外 HTTP API 变更时**强制** → 走 `api-verification` Skill |
| 验证项 | 正常响应码 · 字段结构 · 错误码(400/401/404/500)|
> ⚠️ API 测试产物(`.http`/`.cjs`)是 `api-verification` Skill 的专属输出,本 Skill 不重复定义;本 Skill 仅规定覆盖目标与触发条件。
### E2E 测试(End-to-End Test)
| 项 | 规范 |
|----|------|
| 工具 | Playwright(推荐)/ Cypress |
| 产物路径 | `tests/e2e/` |
| 覆盖目标 | 核心用户流程(登录/核心业务主流程)必须有 E2E 覆盖 |
| 触发要求 | 用户可见交互或关键业务流程新增/变更时 |
| 数据策略 | 专属测试账号/测试环境,禁止使用生产数据 |
## 测试失败处理规范
| 场景 | 处理方式 |
|------|---------|
| 静态/类型检查失败 | 🔴 阻断交付/收尾,必须修复后才能宣告任务完成 |
| 单元/集成测试失败 | 🔴 阻断交付/收尾,必须修复后才能宣告任务完成 |
| API 测试失败 | 🔴 阻断,回 CP2 修订接口方案 |
| E2E 测试失败 | 按 TestRoute 风险判定:核心用户路径、发布门禁或安全/数据关键路径失败为 🔴;非阻断实验/辅助路径可 🟡,必须记录分类依据与残余风险 |
| 超过 2 次迭代仍失败 | 停止,输出错误摘要 ⚠️,等待用户决策 |
## 重构前置测试检查(dev.refactor 强制)
```text
[检查已有测试覆盖] → 有测试 → 继续重构
→ 无测试 → ⛔ 禁止继续,优先补单元测试再重构
```
**基线快照(重构前记录)**:
- 接口签名(函数名/参数/返回类型)
- 导出列表
- 现有测试通过率(作为重构后回归基准)
**重构后验证**:
- 所有原有测试必须全部通过(行为不变原则)
- 新增代码覆盖补充到 ≥ 基线水平
## 覆盖率报告
- 测试完成后输出覆盖率报告到任务目录报告区:`<任务目录>/reports/<agent>/YYYYMMDD/NN--测试覆盖率报告.md`
- 无任务上下文时才回退到项目级:`reports/requirements/<agent>/YYYYMMDD/NN--测试覆盖率报告.md`
- 内容包含各类型实际覆盖率 vs 目标对比,并引用本次测试命令与结果