关于 cover
Cover 是一种适用于不同宿主环境的技能,可为现有代码生成测试套件,覆盖范围发现、分析、执行和报告。它支持单元、集成和 E2E 测试层级、真实服务测试,以及自动诊断和修复测试失败的循环。
主要功能
- 01发现测试框架与代码范围
- 02按风险排序分析覆盖缺口
- 03生成单元、集成和 E2E 测试
- 04使用真实服务或模拟对象测试
- 05自动诊断并修复测试失败
- 06报告覆盖率与测试结果
适用场景
- 01为现有代码模块生成测试
- 02按选定层级补充测试
- 03针对真实服务测试集成
- 04诊断并修复生成测试中的失败
MCP 相关
工作流会探测可用的 MCP 工具,包括 memory 搜索和 Context7 库查询,并记录能力信息。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ yonatangross/ orchestkit --skill cover安装后在 Claude Code 中输入/cover确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
test-cases.jsonreferences/behaviour-gate.mdclaude-code.mdcoverage-report-template.mdheal-loop-strategy.mdreal-service-detection.mdscripts/check-behaviour-tests.mjsworkflows/heal-loop.js详细介绍
Cover:测试套件生成器
与宿主无关的工作流。通过技能名称(cover)调用。Claude Code 斜杠命令路由、YAML 钩子加载器和 .claude/chain 相关内容见 references/claude-code.md。
为现有代码生成全面的测试套件,包含真实服务集成测试和自动故障修复。
**注意:**如果启用了
disableSkillShellExecution(CC 2.1.91),将不会运行 vitest/jest 的前置条件检查。继续操作前,请确认已安装测试运行器:npx vitest --version或npx jest --version。
快速开始
cover authentication flow
cover --model=opus payment processing
cover --tier=unit,integration user service
cover --real-services checkout pipeline
参数解析
代词目标(this、them、the above)从对话中回溯读取,用一行话说明后使用:Read("../../shared/rules/target-resolution.md"),内联执行一半。
SCOPE = "$ARGUMENTS" # e.g., "authentication flow"
# Flag parsing
MODEL_OVERRIDE = None
TIERS = ["unit", "integration", "e2e"] # default: all three
REAL_SERVICES = False
for token in "$ARGUMENTS".split():
if token.startswith("--model="):
MODEL_OVERRIDE = token.split("=", 1)[1]
SCOPE = SCOPE.replace(token, "").strip()
elif token.startswith("--tier="):
TIERS = token.split("=", 1)[1].split(",")
SCOPE = SCOPE.replace(token, "").strip()
elif token == "--real-services":
REAL_SERVICES = True
SCOPE = SCOPE.replace(token, "").strip()
步骤 -0.5:根据投入程度调整覆盖范围(CC 2.1.76,2.1.120 起支持环境变量)
首先读取 $CLAUDE_EFFORT(CC 2.1.120+);显式的 --effort= 标记优先作为覆盖值。若 CC < 2.1.120 且未提供标记,默认值为 high。模式与 assess + explore(#1540)相符。按以下级别调整测试生成深度:
| 投入程度 | 生成层级 | Agent 数量 | 通过第 5 阶段所需的 maxIterations |
|---|---|---|---|
| low | 仅单元测试 | 1 个 Agent | 2(1 次修复 + 1 次验证) |
| medium | 单元测试 + 集成测试 | 2 个 Agent | 2(1 次修复 + 1 次验证) |
| high(默认) | 单元测试 + 集成测试 + 端到端测试 | 3 个 Agent | 3(2 次修复 + 1 次验证) |
| xhigh(CC 2.1.111+) | 单元测试 + 集成测试 + 端到端测试 | 3 个 Agent | 3(上限;xhigh 会增加 Agent 数量,而不是修复轮数) |
这些值是第 5 阶段中传入 maxIterations 的值。脚本(heal-loop.js)会将其限制在 [2, 3] 范围内,因此超出此范围的值会被调整,且最后一次迭代始终用于验证,而非修复。不存在 4 轮迭代模式。
**覆盖设置:**显式的
--tier=标记或用户选择会覆盖/effort的降级设置。
步骤 -1:MCP 探测 + 恢复检查
# Probe MCPs (parallel):
# memory is alwaysLoad in .mcp.json (CC 2.1.121+, #1541). Probe below kept as fallback for older CC:
ToolSearch(query="select:mcp__memory__search_nodes")
ToolSearch(query="select:mcp__context7__resolve-library-id")
Write(".claude/chain/capabilities.json", {
"memory": <true if found>,
"context7": <true if found>,
"skill": "cover",
"timestamp": now()
})
# Resume check:
Read(".claude/chain/state.json")
# If exists and skill == "cover": resume from current_phase
# Otherwise: initialize state
步骤 0:范围与层级选择
AskUserQuestion(
questions=[
{
"question": "What test tiers should I generate?",
"header": "Test Tiers",
"options": [
{"label": "Full coverage (Recommended)", "description": "Unit + Integration (real services) + E2E"},
{"label": "Unit + Integration", "description": "Skip E2E, focus on logic and service boundaries"},
{"label": "Unit only", "description": "Fast isolated tests for business logic"},
{"label": "E2E only", "description": "Playwright browser tests"}
],
"multiSelect": false
},
{
"question": "Healing strategy for failing tests?",
"header": "Failure Handling",
"options": [
{"label": "Auto-heal (Recommended)", "description": "Fix failing tests up to 3 iterations"},
{"label": "Generate only", "description": "Write tests, report failures, don't fix (skips the heal loop)"},
{"label": "Strict", "description": "All tests must pass or abort"}
],
"multiSelect": false
}
]
)
根据所选内容覆盖 TIERS。如果已提供 --tier= 标记,则跳过此步骤。
**完成标准。**完成意味着:每个生成的测试都能运行,测试套件全部通过,或逐一报告所有剩余失败及其修复循环分类,并且已生成覆盖率报告。遵循 Read("../../shared/rules/long-run-protocol.md"):如果某步骤不需要用户输入,就继续执行;只有在无法继续或即将进行破坏性操作前,才停下来询问;接受每个子 Agent 的结果前先检查其证据;对于无法确认的事项,注明检查位置。
任务管理(必需)
# 1. Create main task IMMEDIATELY
TaskCreate(subject=f"Cover: {SCOPE}", description="Generate comprehensive test suite with real-service testing", activeForm=f"Generating tests for {SCOPE}")
# 2. Create subtasks for each phase
TaskCreate(subject="Discover scope and detect frameworks", activeForm="Discovering test scope") # id=2
TaskCreate(subject="Analyze coverage gaps", activeForm="Analyzing coverage gaps") # id=3
TaskCreate(subject="Generate tests (parallel per tier)", activeForm="Generating tests") # id=4
TaskCreate(subject="Execute generated tests", activeForm="Running tests") # id=5
TaskCreate(subject="Heal failing tests", activeForm="Healing test failures") # id=6
TaskCreate(subject="Generate coverage report", activeForm="Generating report") # id=7
# 3. Set dependencies for sequential phases
TaskUpdate(taskId="3", addBlockedBy=["2"]) # Analysis needs discovery first
TaskUpdate(taskId="4", addBlockedBy=["3"]) # Generation needs gap map
TaskUpdate(taskId="5", addBlockedBy=["4"]) # Execution needs generated tests
TaskUpdate(taskId="6", addBlockedBy=["5"]) # Healing needs test results
TaskUpdate(taskId="7", addBlockedBy=["6"]) # Report needs healed suite
# 4. Update status as you progress
TaskUpdate(taskId="2", status="in_progress") # When starting
TaskUpdate(taskId="2", status="completed") # When done, repeat for each subtask
6 阶段工作流
| 阶段 | 活动 | 输出 |
|---|---|---|
| 1. 探索 | 检测框架、扫描范围、查找未测试代码 | 框架映射、文件列表 |
| 2. 覆盖率分析 | 运行现有测试,按层级对风险目标排序 | 覆盖率基线、附带原因的风险目标 |
| 3. 生成 | 按层级并行启动测试生成 Agent,然后进行行为门控 | 创建的测试文件、门控判定 |
| 4. 执行 | 运行所有生成的测试 | 通过/失败结果 |
| 5. 修复 | 修复失败并重新运行(最多 3 轮) | 全部通过的测试套件 |
| 6. 报告 | 覆盖率变化、测试数量、摘要 | 覆盖率报告 |
阶段交接
| 阶段之后 | 交接文件 | 关键输出 |
|---|---|---|
| 1. 探索 | 01-cover-discovery.json | 框架、范围文件、层级计划 |
| 2. 分析 | 02-cover-analysis.json | 覆盖率基线、附带原因的风险目标 |
| 3. 生成 | 03-cover-generation.json | 创建的文件、各层级测试数量、行为门控判定 |
| 5. 修复 | 05-cover-healed.json | 最终通过/失败结果、使用的迭代次数 |
第 1 阶段:发现
检测项目的测试基础设施并确定工作范围。
# PARALLEL, all in ONE message:
# 1. Framework detection (hook handles this, but also scan manually)
Grep(pattern="vitest|jest|mocha|playwright|cypress", glob="package.json", output_mode="content")
Grep(pattern="pytest|unittest|hypothesis", glob="pyproject.toml", output_mode="content")
Grep(pattern="pytest|unittest|hypothesis", glob="requirements*.txt", output_mode="content")
# 2. Real-service infrastructure
Glob(pattern="**/docker-compose*.yml")
Glob(pattern="**/testcontainers*")
Grep(pattern="testcontainers", glob="**/package.json", output_mode="content")
Grep(pattern="testcontainers", glob="**/requirements*.txt", output_mode="content")
# 3. Existing test structure
Glob(pattern="**/tests/**/*.test.*")
Glob(pattern="**/tests/**/*.spec.*")
Glob(pattern="**/__tests__/**/*")
Glob(pattern="**/test_*.py")
# 4. Scope files (what to test)
# If SCOPE specified, find matching source files
Grep(pattern=SCOPE, output_mode="files_with_matches")
真实服务判定:
- 找到
docker-compose*.yml→ 集成测试使用真实服务 - 依赖中包含
testcontainers→ 使用 testcontainers 隔离服务实例 - 两者都未找到 +
--real-services标志 → 错误:“No docker-compose or testcontainers found. Install testcontainers or remove --real-services flag.” - 两者都未找到,且没有标志 → 集成测试使用模拟(MSW/VCR)
加载真实服务检测详情:Read("references/real-service-detection.md")
第 2 阶段:覆盖率分析与风险目标
先运行现有测试作为基线,然后按风险选择目标。覆盖率仅供报告参考,绝不是目标。
# Baseline: npx vitest run --coverage --reporter=json | pytest --cov=<scope> --cov-report=json | go test -coverprofile=coverage.out ./...
# Rank uncovered code by risk and record WHY each target was chosen:
# changed code, complex branches, error paths, security and money paths, past bugs
# gap_map[tier] = [{"target": "src/billing/refund.ts:roundRefund", "why": "money path, fixed in #812"}]
立即输出基线和按风险排序的目标,并说明每个目标的原因(渐进式输出)。信号及其查找方法:Read("references/behaviour-gate.md")。
第 3 阶段:生成(并行 Agent)
按层级启动测试生成 Agent。通过一条消息全部启动,并设置 run_in_background=true。
隔离: 每个层级的 Agent 都要使用
Agent(isolation="worktree")启动,每个层级(单元 / 集成 / 端到端)使用一个 worktree,避免相互冲突。子 Agent 绕过 worktree 隔离保护的问题已在 CC 2.1.154 修复,并在 2.1.203 完成;ork 的最低版本为 >= 2.1.220,因此所有受支持的会话都能获得真正的隔离。启动前不要手动创建 worktree。新分支的基准来自
worktree.baseRef设置,绝不能使用硬编码的分支名称。ork 不会设置此项:插件做不到,而且 ork 的设置文件中也没有该项。除非操作员在.claude/settings.json或~/.claude/settings.json中设置了"baseRef": "head",否则会采用 CC 的默认值"fresh":每个层级的 Agent 都会从origin/<default>创建分支,尚未推送的本地提交对其不可见,而且tsc会因找不到你刚编写的代码而报“cannot find module”。启动前请确认该设置。完整模式:Read("../chain-patterns/references/worktree-agent-pattern.md")
# Unit tests agent (worktree-isolated)
if "unit" in TIERS:
Agent(
subagent_type="ork:test-generator",
isolation="worktree",
prompt=f"""Generate unit tests for: {SCOPE}
Risk targets, each with why: {gap_map["unit"]}
Framework: {detected_framework}
Existing tests: {existing_test_files}
Focus on:
- AAA pattern (Arrange-Act-Assert)
- Parametrized tests for multiple inputs
- MSW/VCR for HTTP mocking (never mock fetch directly)
- Factory-based test data (FactoryBoy/faker-js)
- Edge cases: empty input, errors, timeouts, boundary values
- BEHAVIOUR GATE: write a test ONLY if it asserts an observable result. Never write a
mock-call-only, assertion-free, tautological, or source-reading test (references/behaviour-gate.md)""",
run_in_background=True,
max_turns=50,
model=MODEL_OVERRIDE
)
# Integration + E2E agents follow the same pattern:
# - subagent_type="ork:test-generator", isolation="worktree", run_in_background=True, same targets + BEHAVIOUR GATE lines
# - Integration focus: API endpoints (Supertest/httpx), real DB, contract tests (Pact), Zod schema validation
# - E2E focus: Playwright, semantic locators, Page Object Model, axe-core a11y, visual regression
#
# Special case: emulate (Vercel Labs stateful API emulation):
# When integration tests need GitHub/Stripe/Resend/Okta/etc. emulated
# (HMAC webhooks, parallel port isolation, full config from scratch),
# spawn emulate-engineer instead of test-generator for that tier:
# - subagent_type="ork:emulate-engineer" (same isolation="worktree" form)
# - Pairs with emulate-seed skill for seed YAML patterns
每个 Agent 一返回结果,就立即输出。不要等所有 Agent 都完成。
第 3b 阶段:行为门禁
第 4 阶段之前,对仅包含新增测试文件的文件列表运行 node "${CLAUDE_SKILL_DIR}/scripts/check-behaviour-tests.mjs" --json <new test files>。退出代码为 1 时,会按规则列出每个被拒绝的测试:(a) 仅断言模拟调用;(b) 没有断言、仅有同义反复式断言(expect(true).toBe(true)),或在“不抛出错误”并非声明契约时仅断言不抛出错误;(c) 读取或 grep 源代码,而不是执行源代码。删除每个被拒绝的测试(对于 drop,删除整个文件,这表示所有被识别的测试都遭到拒绝),或将其改写为断言可观察到的结果,然后重新运行,直至退出代码为 0。绝不要删除 unchecked 文件或测试(未识别出测试,或其测试主体在其他位置声明);应手动审查。第 5 阶段之后再次运行。将判定结果记录在 03-cover-generation.json 中。规则和限制:Read("references/behaviour-gate.md")。
专注模式(CC 2.1.101): 在专注模式下,最终消息中须包含完整覆盖率报告(前后差异、各层级的测试数量、新建文件)。
第 4 阶段:执行
运行所有生成的测试并收集结果。
# Run test commands per tier (PARALLEL if independent):
# Unit: npx vitest run tests/unit/ OR pytest tests/unit/
# Integration: npx vitest run tests/integration/ OR pytest tests/integration/
# E2E: npx playwright test
# Collect: pass count, fail count, error details, coverage delta
阶段 5:修复循环
**不要手工编写循环。**运行真实的执行器:
Workflow(
scriptPath="${CLAUDE_SKILL_DIR}/workflows/heal-loop.js",
args={"testCommand": "<tier test command>", "tier": "unit", "testGlob": "tests/unit/",
"maxIterations": 3} # from the effort table above; omitted defaults to 3
)
# One invocation per tier that has failures.
**扇出规则:**当所选的失败处理方式会运行修复循环时,单次运行绝不能作为后备方案。每个存在失败的层级都必须调用修复循环工作流;如果工作流未运行,则以 BLOCKED 结束运行,并说明原因。“仅生成”会跳过修复循环,因此不算违反规则。
迭代次数上限由脚本强制执行,而非依靠指令。heal-loop.js
会运行一个真实的计数循环,迭代次数限制在 [2, 3]:每次迭代都会启动一个诊断 Agent,实际执行测试命令,并返回结构化的通过/失败结果和原样的失败输出;随后启动一个修复 Agent,接收该失败文本,且只编辑测试文件。只要测试套件通过,就会立即提前退出。
最后一次迭代只进行诊断,不执行修复——因为修复后就没有剩余运行次数来验证了。因此,maxIterations: N 表示运行 N 次诊断和 N-1 次修复;默认值 3 表示修复 2 次。上限设为 1 时会强制调整为 2,因为 1 就意味着一次修复也不会执行。
每个失败都会按照分类体系归类(assertion、import、setup、timeout、stale-selector、type、flaky,以及 source-bug),并据此选择修复策略。
工作流会返回 status: "healed" 或结构化失败结果(status: "failed"、healed: false),其中包含 remaining_failures、failure_categories 和逐次迭代记录。绝不能将 "failed" 结果报告为成功:应在阶段 6 报告中列出仍然失败的测试。
策略详情(分类表、修复规则、防止不稳定测试):Read("references/heal-loop-strategy.md")
**边界:修复循环修复的是测试,而不是源代码。**如果测试失败是因为源代码存在 bug,应予以报告。不要悄悄修复生产代码。
阶段 6:报告
生成覆盖率报告,并比较前后变化。
完整报告布局(基线→完成后的对比表、生成的测试数量、修复迭代次数、创建的文件、剩余差距、后续步骤命令):Read("references/coverage-report-template.md")。
完成时发送 PushNotification(CC 2.1.110+)
完整的 cover 运行(单元测试 + 集成测试 + E2E 测试及修复循环)需要 15-45 分钟。完成阶段 6 报告后,调用 PushNotification(message=f"ork:cover complete, {SCOPE}: {tests_kept} tests kept · {tests_dropped} dropped by behaviour gate · {heal_loops} heal iters", status="proactive")。完整规则:Read("../chain-patterns/rules/push-notification-on-completion.md")。
覆盖率漂移监控(CC 2.1.71)
可选择安排每周检查,确保风险目标仍有对应的行为测试:
# Guard: Skip cron in headless/CI (CLAUDE_CODE_DISABLE_CRON)
# if env CLAUDE_CODE_DISABLE_CRON is set, run a single check instead
CronCreate(
schedule="0 2 * * 0",
prompt="Weekly drift check for {SCOPE}: run the tests covering the risk targets in 02-cover-analysis.json.
Alert if one was deleted or fails, or if newly changed code has no behaviour test. Coverage is reported as information only."
)
核心原则
- **输出限制(CC 2.1.77+):**Opus 4.8 默认最多输出 64k 个 token(上限为 128k)。对于大型测试套件,如果输出接近限制,应分多个 Agent 轮次生成。
- **部分读取(CC 2.1.144+):**对于过大的文件,Read 会先返回第一页
[PARTIAL view](这不是错误)。应使用明确的offset/limit重新读取,以确保覆盖率分析能查看完整文件。 - **仅限测试:**绝不修改生产源代码,只生成测试文件
- **优先使用可用的真实服务:**集成测试优先使用 testcontainers/docker-compose,而非模拟对象,因为模拟对象与生产环境的差异会导致生产环境中出现无声失败
- **并行生成:**在同一条消息中,为每个层级启动一个测试生成 Agent
- **修复问题,不要无限循环:**最多迭代 3 次,然后报告剩余失败
- **逐步输出:**每个 Agent 完成后立即展示结果
- **优先使用工厂而非固定数据:**使用 FactoryBoy/faker-js 生成测试数据,而非硬编码值
- **在网络层进行模拟:**使用 MSW/VCR,绝不直接模拟 fetch/axios
Agent 协同
上下文传递
每个测试生成 Agent 都会收到:其所在层级的风险目标(各目标均附带原因)、行为门控规则、测试框架配置、真实服务基础设施(testcontainers、docker-compose),以及项目中的固定数据模式。
监控 + 部分结果(CC 2.1.98)
使用 Monitor 流式查看后台 Agent 的测试执行输出:
# Stream test suite output in real-time
Bash(command="npm test -- --coverage 2>&1", run_in_background=true)
Monitor(pid=test_task_id) # Each line → notification
完整模式参考(until-condition 门控、部分结果补救、TaskOutput 与 Monitor 的选择):Read("../chain-patterns/references/monitor-patterns.md")。
**部分结果(CC 2.1.98):**如果测试生成器在生成过程中崩溃,请综合利用它已生成的内容:
for agent_result in test_gen_results:
if "[PARTIAL RESULT]" in agent_result.output:
# Agent crashed: check if it wrote any test files before dying
partial_tests = Glob(pattern="**/tests/**/*.test.*", path=agent_result.worktree)
if partial_tests:
# 6 passing tests from a crashed agent > 0 tests
# Copy partial tests to main worktree, run them in Phase 4
for test_file in partial_tests:
Bash(command=f"cp {test_file} {main_worktree}/{test_file}")
# Flag as partial in report
从 CC 2.1.246 起,maxTurns 停止也属于部分结果(摘要:“在其 N 轮限制处停止(部分结果;使用 SendMessage 向 task-id 继续执行)”);请使用 SendMessage 让该 Agent 继续,而不是重新启动它。
SendMessage(测试修复)
**跨会话回复会发送到父会话(CC 2.1.248):**当子 Agent 向另一个会话发送
SendMessage时,回复会发送到父会话的对话中,而不会发送给子 Agent;子 Agent 发送消息后继续执行,父会话读取回复。跨会话的SendMessage/ListAgents也可在 Bedrock、Vertex 和 Foundry 上使用,并且在遥测禁用时也可使用(CC 2.1.248)。
生成的测试失败时,修复 Agent 可以向生成器请求上下文:
SendMessage(to="test-generator-unit", message="Test user_service_test.py:42 fails: TypeError on mock return. What's the expected shape?")
技能链
标准链:implement → cover → verify → commit。在各步骤之间使用 addBlockedBy。
验证门槛
在声称覆盖完整之前,应用:Read("../../shared/rules/verification-gate.md")。重新运行覆盖率报告。“应该通过”不是证据。
Agent 状态协议
所有测试生成器 Agent 都使用以下方式报告:Read("../../shared/status-protocol.md")。如果因缺少接口而无法编写测试,则报告 BLOCKED。如果测试预期不明确,则报告 NEEDS_CONTEXT。
质量标准
满足以下所有条件才算完成:
- 覆盖率报告展示实际覆盖率命令输出中的前后差异,而非估算值
- 每个生成的测试文件都已执行;粘贴测试运行器的最终通过/失败数量
- Phase 5 后,新测试文件的行为门槛退出码为 0,且每个目标都说明了选择原因
- 未修改生产源代码(仅创建测试文件);发现源代码 Bug 时应报告,绝不能悄悄修复
- 在迭代预算(≤3,按工作量调整)内修复失败,或明确报告剩余失败数量
- 每个请求的测试层级(单元/集成/端到端)都已生成测试,或说明跳过原因
相关技能
ork:implement:在实现过程中生成测试(Phase 5);之后使用cover深入提升覆盖率ork:verify:为现有测试评分(0-10);链:implement → cover → verifytesting-unit/testing-integration/testing-e2e:由测试生成器 Agent 加载的知识技能ork:commit:提交生成的测试文件
**会话恢复(CC 2.1.108+):**在闲置或中断后,使用
/recap恢复对话上下文以及检查点恢复状态。自 CC 2.1.110 起默认启用(即使遥测已禁用)。
参考资料
按需使用 Read("references/<file>") 加载:
| 文件 | 内容 |
|---|---|
real-service-detection.md | Docker-compose/testcontainers 检测、服务启动和 teardown |
heal-loop-strategy.md | 失败分类、修复模式、迭代预算 |
coverage-report-template.md | 报告格式、差异计算、差距分析 |
behaviour-gate.md | 风险目标信号、三条拒绝规则、检查器的用法和限制 |
scripts/check-behaviour-tests.mjs | Phase 3b 检查器:逐个判定新测试文件应保留还是拒绝 |
workflows/heal-loop.js | Phase 5 执行器:由脚本强制执行的 3 轮修复循环(通过 Workflow 工具运行) |
**版本:**1.3.0(September 2026):行为门槛(Phase 3b 检查器)和基于风险的目标取代百分比覆盖率目标