- name
- cover
- license
- MIT
- compatibility
- Claude Code 2.1.277+. Requires network access.
- description
- Generate tests that do not exist yet. Analyzes coverage gaps, then writes and runs new test files across three tiers (unit, integration via testcontainers, Playwright E2E), one test-generator agent per tier, healing failures for up to 3 iterations. Use when code has no tests or when raising coverage after implementation. Do NOT use to grade tests that already exist (use /ork:verify) or to run a suite without writing anything new.
- argument-hint
- [scope-or-feature]
- context
- fork
- background
- false
- user-invocable
- true
- allowed-tools
- SendMessage AskUserQuestion Bash Read Write Edit Grep Glob Agent TaskCreate TaskUpdate TaskList TaskStop ToolSearch Workflow CronCreate CronDelete Monitor PushNotification mcp__memory__search_nodes mcp__context7__resolve-library-id mcp__context7__query-docs
- skills
- ["testing-unit","testing-integration","testing-e2e","testing-perf","testing-llm","chain-patterns","memory","quality-gates"]
- effort
- high
- model
- sonnet
- hooks
- {"PreToolUse":[{"matcher":"Bash","command":"${CLAUDE_PLUGIN_ROOT}/hooks/bin/run-hook.mjs skill/test-framework-detector","once":true}]}
- metadata
- {"category":"workflow-automation","mcp-server":"memory, context7","version":"1.3.0","author":"OrchestKit","complexity":"high","tags":"testing, coverage, unit, integration, e2e, test-generation, real-services, testcontainers"}
- paths
- ["src/**/*.test.{ts,tsx,js}","**/.coveragerc","vitest.config.*","jest.config.*"]
- invocation_hooks
- ["command -v vitest >/dev/null 2>&1 || command -v jest >/dev/null 2>&1 || echo 'Warning: no test runner found: run npm install first'"]
# Cover: Test Suite Generator
Host-neutral workflow. Invoke by skill name (`cover`). Claude Code slash routing, YAML hook loaders, and `.claude/chain` live in `references/claude-code.md`.
Generate comprehensive test suites for existing code with real-service integration testing and automated failure healing.
> **Note:** If `disableSkillShellExecution` is enabled (CC 2.1.91), the precondition check for vitest/jest won't run. Verify a test runner is installed before proceeding: `npx vitest --version` or `npx jest --version`.
## Quick Start
```bash
cover authentication flow
cover --model=opus payment processing
cover --tier=unit,integration user service
cover --real-services checkout pipeline
```
## Argument Resolution
```python
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()
```
---
## Step -0.5: Effort-Aware Coverage Scaling (CC 2.1.76, env var since 2.1.120)
Read `$CLAUDE_EFFORT` (CC 2.1.120+) first; explicit `--effort=` token wins as override. Default `high` when CC < 2.1.120 and no flag. Pattern matches assess + explore (#1540). Scale test generation depth:
| Effort Level | Tiers Generated | Agents | `maxIterations` to pass Phase 5 |
|-------------|----------------|--------|-----------------|
| **low** | Unit only | 1 agent | 2 (1 repair + 1 verify) |
| **medium** | Unit + Integration | 2 agents | 2 (1 repair + 1 verify) |
| **high** (default) | Unit + Integration + E2E | 3 agents | 3 (2 repairs + 1 verify) |
| **xhigh** (CC 2.1.111+) | Unit + Integration + E2E | 3 agents | 3 (the ceiling; xhigh adds agents, not heal passes) |
Values are what you pass as `maxIterations` in Phase 5. The script clamps to `[2, 3]`
(`heal-loop.js`), so anything outside that range is coerced, and the final iteration always
verifies rather than repairing. There is no 4-iteration mode.
> **Override:** Explicit `--tier=` flag or user selection overrides `/effort` downscaling.
## Step -1: MCP Probe + Resume Check
```python
# 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
```
---
## Step 0: Scope & Tier Selection
```python
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"},
{"label": "Strict", "description": "All tests must pass or abort"}
],
"multiSelect": false
}
]
)
```
Override TIERS based on selection. Skip this step if `--tier=` flag was provided.
---
**Finish line.** Done means: every generated test runs, the suite is green or each remaining failure is reported with its heal-loop classification, and the coverage report is written. Follow `Read("../../shared/rules/long-run-protocol.md")`: keep going when a step needs no input from the user, stop and ask only when you can't continue without them or before anything destructive, check each subagent's evidence before accepting it, and mark anything you couldn't confirm with where you looked.
## Task Management (MANDATORY)
```python
# 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-Phase Workflow
| Phase | Activities | Output |
|-------|------------|--------|
| **1. Discovery** | Detect frameworks, scan scope, find untested code | Framework map, file list |
| **2. Coverage Analysis** | Run existing tests, rank risk targets per tier | Coverage baseline, risk targets with why |
| **3. Generation** | Parallel test-generator agents per tier, then behaviour gate | Test files created, gate verdicts |
| **4. Execution** | Run all generated tests | Pass/fail results |
| **5. Heal** | Fix failures, re-run (max 3 iterations) | Green test suite |
| **6. Report** | Coverage delta, test count, summary | Coverage report |
### Phase Handoffs
| After Phase | Handoff File | Key Outputs |
|-------------|-------------|-------------|
| 1. Discovery | `01-cover-discovery.json` | Frameworks, scope files, tier plan |
| 2. Analysis | `02-cover-analysis.json` | Baseline coverage, risk targets with why |
| 3. Generation | `03-cover-generation.json` | Files created, test count per tier, behaviour gate verdicts |
| 5. Heal | `05-cover-healed.json` | Final pass/fail, iterations used |
---
### Phase 1: Discovery
Detect the project's test infrastructure and scope the work.
```python
# 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")
```
**Real-service decision:**
- `docker-compose*.yml` found → integration tests use real services
- `testcontainers` in deps → use testcontainers for isolated service instances
- Neither found + `--real-services` flag → error: "No docker-compose or testcontainers found. Install testcontainers or remove --real-services flag."
- Neither found, no flag → integration tests use mocks (MSW/VCR)
Load real-service detection details: `Read("references/real-service-detection.md")`
### Phase 2: Coverage Analysis and Risk Targets
Run existing tests for a baseline, then pick targets by RISK. Coverage is information for the report, never a target.
```python
# 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"}]
```
Output the baseline and the risk-ranked targets, each with its why, immediately (progressive output). Signals and how to find them: `Read("references/behaviour-gate.md")`.
### Phase 3: Generation (Parallel Agents)
Spawn test-generator agents per tier. Launch ALL in ONE message with `run_in_background=true`.
> **Isolation:** spawn each tier agent with `Agent(isolation="worktree")`, one
> worktree per tier (unit / integration / e2e) so they don't conflict. The
> subagent bypass of the worktree-isolation guard was fixed in CC 2.1.154 and
> completed in 2.1.203; ork's floor is >= 2.1.220, so every supported session
> gets real isolation. Do not create worktrees by hand before spawning.
>
> The new branch's base comes from the `worktree.baseRef` setting, never from a
> hardcoded branch name. **ork does not set it**: a plugin cannot, and no ork
> settings file carries it. Unless the operator put `"baseRef": "head"` in
> `.claude/settings.json` or `~/.claude/settings.json`, CC's default `"fresh"`
> applies: every tier agent branches from `origin/<default>`, unpushed local
> commits are invisible to it, and `tsc` fails with "cannot find module" for
> code you just wrote. Verify the setting before spawning. Full pattern:
> `Read("../chain-patterns/references/worktree-agent-pattern.md")`
```python
# 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
GitHub에서 보기