test
Generate tests and coverage plans.
What this skill does
# Test Skill
> **Quick Ref:** Generate tests, analyze coverage, fill gaps, run TDD loops. Output: passing tests + coverage report in `.agents/test/`.
**YOU MUST EXECUTE THIS WORKFLOW. Do not just describe it.**
Generate real tests, run them, verify they pass, and produce coverage artifacts. Do not output a plan and stop.
## Modes
| Mode | Trigger | What It Does |
|------|---------|--------------|
| `generate` | "generate tests", "write tests", "add tests" | Create tests for existing code |
| `coverage` | "test coverage", "coverage gaps", "missing tests" | Analyze coverage and fill gaps |
| `strategy` | "test strategy", "test architecture" | Recommend test structure and patterns |
| `tdd` | "tdd", "red green refactor" | Red-green-refactor loop for new features |
Default mode is `generate` when unspecified. Detect from user intent.
## Step 0a: Scenarios-First (when the work has acceptance scenarios)
When the task is tied to a bead or `.feature` file, **author tests FORWARD from the Gherkin scenarios** — not backward from a coverage gap. This is the C2 contract (ag-9jle.4): the unit of test authoring is one scenario, one covering test.
1. Read the scenarios: the bead's `## Scenarios` block (`bd show <bead-id>`) or a `.feature` under `skills/<skill>/references/`.
2. For each `Scenario:`, locate or write the test that exercises its `Given/When/Then`. Name it after the behavior.
3. Declare the linkage by adding `@covered-by:<test-path>` (optionally `::<TestName>`) directly above the scenario in its source — so the leaf coverage gate can prove the mapping.
4. Run the leaf coverage gate and require it to pass before considering the slice tested:
```bash
bash scripts/check-bead-scenario-coverage.sh --bead <bead-id> --run # every scenario -> a PASSING test
bash scripts/check-bead-scenario-coverage.sh skills/<skill>/references/<name>.feature --run
```
A scenario with no covering test is a FAIL — "tests exist" or a coverage percentage is not sufficient. Then continue with coverage gap-fill (Steps 1–5) for everything the scenarios don't reach. When there are no scenarios, skip this step and use the coverage-driven flow below.
## Step 0: Detect Language and Load Standards
Scan the project root for language markers. Stop at the first match:
| Marker File | Language | Test Framework | Coverage Command |
|-------------|----------|----------------|-----------------|
| `go.mod` | Go | `go test` | `go test -coverprofile=coverage.out ./...` |
| `pyproject.toml` or `setup.py` | Python | pytest | `pytest --cov --cov-report=term-missing` |
| `package.json` | JS/TS | jest or vitest | `npx jest --coverage` or `npx vitest run --coverage` |
| `Cargo.toml` | Rust | cargo test | `cargo tarpaulin --out Lcov` |
Load `/standards` for the detected language. Apply all testing conventions from the standards skill (naming, assertion style, structural rules).
**Go-specific rules (from project CLAUDE.md):**
- Test file naming: `<source>_test.go`. NEVER `cov*_test.go` or `*_extra_test.go`.
- Test function naming: `Test<Uppercase>` (e.g., `TestParseConfig_EmptyInput`).
- Prefer table-driven tests for multi-case functions.
- Use `captureStdout` for output functions and assert content.
**Python-specific rules:**
- Use `pytest` with `conftest.py` for shared fixtures.
- Use `@pytest.mark.parametrize` for multi-case functions.
- Type hints on test helpers.
**JS/TS-specific rules:**
- Use `describe`/`it` blocks with clear names.
- Group by function or module under test.
- Mock external services, not internal code.
## Step 1: Analyze Existing Test Coverage
Run the coverage command for the detected language:
```bash
# Go
go test -coverprofile=coverage.out ./... 2>&1 | tee .agents/test/coverage-raw.txt
go tool cover -func=coverage.out > .agents/test/coverage-func.txt
# Python
pytest --cov --cov-report=term-missing --cov-report=json:.agents/test/coverage.json 2>&1 | tee .agents/test/coverage-raw.txt
# JS/TS
npx jest --coverage --coverageReporters=text 2>&1 | tee .agents/test/coverage-raw.txt
# Rust
cargo tarpaulin --out Lcov 2>&1 | tee .agents/test/coverage-raw.txt
```
Parse the output. Build a ranked list of files by coverage percentage (lowest first).
If `/complexity` is available, cross-reference: high-complexity + low-coverage = highest priority targets.
## Step 2: Identify Gaps
From the coverage data, identify:
1. **Untested files** -- source files with no corresponding test file.
2. **Uncovered functions** -- exported/public functions with 0% coverage.
3. **Uncovered branches** -- functions with partial coverage (conditionals, error paths).
4. **Missing edge cases** -- functions that only test the happy path.
Produce a gap list sorted by risk (high complexity + low coverage first):
```
File | Coverage | Functions Missing Tests | Risk
----------------------------|----------|------------------------|------
internal/parser/parse.go | 23% | ParseConfig, Validate | HIGH
internal/goals/measure.go | 45% | MeasureFitness | MEDIUM
lib/utils.go | 89% | (edge cases only) | LOW
```
Write gap list to `.agents/test/gaps.md`.
## Step 3: Generate Tests
For each gap (highest risk first), generate tests following language-specific patterns.
If the target needs a specialized test pattern, load the matching reference before writing tests:
- Contract/API/CLI compatibility: [references/conformance-harnesses.md](references/conformance-harnesses.md)
- Parsers, serializers, and untrusted inputs: [references/fuzzing.md](references/fuzzing.md)
- Generated files, snapshots, and rendered output: [references/golden-artifacts.md](references/golden-artifacts.md)
- Metamorphic/invariant-heavy behavior: [references/metamorphic-testing.md](references/metamorphic-testing.md)
- Golden artifact update review: [references/golden-artifact-strategy.md](references/golden-artifact-strategy.md)
- Real databases, services, queues, or APIs where mocks would hide failures: [references/real-service-e2e.md](references/real-service-e2e.md)
### Go: Table-Driven Tests
```go
func TestParseConfig_Variants(t *testing.T) {
tests := []struct {
name string
input string
want *Config
wantErr bool
}{
{name: "valid minimal", input: `name: foo`, want: &Config{Name: "foo"}},
{name: "empty input", input: "", want: nil, wantErr: true},
{name: "invalid yaml", input: `: bad`, want: nil, wantErr: true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := ParseConfig(tt.input)
if (err != nil) != tt.wantErr {
t.Errorf("ParseConfig() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("ParseConfig() = %v, want %v", got, tt.want)
}
})
}
}
```
### Python: Parametrized Tests
```python
@pytest.mark.parametrize("input_val,expected", [
("valid", Config(name="valid")),
("", None),
(None, None),
])
def test_parse_config(input_val: str, expected: Config | None) -> None:
result = parse_config(input_val)
assert result == expected
```
### JS/TS: Describe Blocks
```typescript
describe("parseConfig", () => {
it("parses valid input", () => {
expect(parseConfig("valid")).toEqual({ name: "valid" });
});
it("returns null for empty input", () => {
expect(parseConfig("")).toBeNull();
});
it("throws on malformed input", () => {
expect(() => parseConfig(": bad")).toThrow();
});
});
```
### Generation Rules
1. **Read the source function first.** Understand inputs, outputs, error conditions, and branches.
2. **Cover every branch.** Each `if`, `switch`, error return, and edge case gets at least one test case.
3. **Assert exact expected values.** Use `== expected`, not `!= nil` or `!= ""`.
4. **Name tests descriptively.** The test name should describeRelated in Code Review
gstack
IncludedFast headless browser for QA testing and site dogfooding. Navigate pages, interact with elements, verify state, diff before/after, take annotated screenshots, test responsive layouts, forms, uploads, dialogs, and capture bug evidence. Use when asked to open or test a site, verify a deployment, dogfood a user flow, or file a bug with screenshots. (gstack)
startup-due-diligence
IncludedLegal due diligence review for seed-stage and Series A startups (US, Delaware C-Corp focus). Supports both investor and founder perspectives. Capabilities include: (1) Interactive document review and issue spotting; (2) Document request list generation; (3) Cap table and SAFE/convertible note analysis; (4) Red flag identification with severity ratings; (5) Diligence report generation. TRIGGERS: due diligence, DD, startup investment, cap table review, Series A, seed round, investor diligence, legal review startup, SAFE analysis, convertible note, 409A, founder vesting.
interview-master
IncludedThis skill should be used when the user asks to "generate interview questions", "prepare for interview", "optimize resume", "conduct mock interview", "analyze git commits for resume", "generate resume from code", "review my resume", or mentions interview preparation, career assistance, or extracting project experience from git history. Provides comprehensive interview and career development guidance for both job seekers and interviewers.
fix-issue
IncludedFixes GitHub issues using parallel analysis agents for root cause investigation, code exploration, and regression detection. Reads issue context from gh CLI, searches codebase and memory for related patterns, generates a fix with tests, and links the resolution back to the issue via PR. Includes prevention analysis to avoid recurrence. Use when debugging errors, resolving regressions, fixing bugs, or triaging issues.
sf-apex
IncludedGenerates and reviews Salesforce Apex code with 150-point scoring. TRIGGER when: user writes, reviews, or fixes Apex classes, triggers, test classes, batch/queueable/schedulable jobs, or touches .cls/.trigger files. DO NOT TRIGGER when: LWC JavaScript (use sf-lwc), Flow XML (use sf-flow), SOQL-only queries (use sf-soql), or non-Salesforce code.
swift-development
IncludedComprehensive Swift development for building, testing, and deploying iOS/macOS applications. Use when Claude needs to: (1) Build Swift packages or Xcode projects from command line, (2) Run tests with XCTest or Swift Testing framework, (3) Manage iOS simulators with simctl, (4) Handle code signing, provisioning profiles, and app distribution, (5) Format or lint Swift code with SwiftFormat/SwiftLint, (6) Work with Swift Package Manager (SPM), (7) Implement Swift 6 concurrency patterns (async/await, actors, Sendable), (8) Create SwiftUI views with MVVM architecture, (9) Set up Core Data or SwiftData persistence, or any other Swift/iOS/macOS development tasks.