java/src/main/resources/targets/claude/skills/core/test/x-test-plan/SKILL.md
Generates a Double-Loop TDD test plan with TPP-ordered scenarios before implementation. Delegates KP reading to a context-gathering subagent, then produces structured Acceptance Tests (outer loop) and Unit Tests in Transformation Priority Premise order (inner loop).
npx skillsauth add edercnj/ia-dev-environment x-test-planInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Produces a Double-Loop TDD test plan that drives implementation order. With 95% line / 90% branch coverage enforced, the plan serves as the implementation roadmap — each test scenario maps to one Red-Green-Refactor cycle, ordered by Transformation Priority Premise (TPP).
/x-test-plan STORY-ID — generate test plan for a specific story| Parameter | Required | Description |
|-----------|----------|-------------|
| STORY-ID | Yes | Story identifier to plan tests for. If not provided, prompt for it. |
0. PRE-CHECK -> Verify existing plan freshness (mtime comparison)
1. GATHER CONTEXT -> Subagent (model: opus) reads testing + architecture KPs, story, template, existing code
2. PLAN TESTS -> Generate Double-Loop + TPP-ordered scenarios (inline)
3. ESTIMATE -> Estimate coverage and validate completeness (inline)
Before generating a test plan, verify whether a valid plan already exists:
Resolve paths: Extract epic ID (XXXX) and story sequence (YYYY) from the story ID. Compute:
plans/epic-XXXX/plans/tests-story-XXXX-YYYY.mdCheck existence: If the plan file does NOT exist, proceed to generation (Step 1).
Compare modification times: If the plan file exists:
mtime(story file) <= mtime(plan file) — the plan is fresh. Log: "Reusing existing test plan from {date}" (where {date} is the plan file's last modified date). Return the existing plan. Do NOT invoke any subagent.mtime(story file) > mtime(plan file) — the plan is stale. Log: "Regenerating stale test plan for {story-id}". Proceed to generation (Step 1).First generation: If the plan file does not exist at all, log: "Generating test plan for {story-id}". Proceed to generation (Step 1).
Bash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh start x-test-plan Phase-1-KP-Read
Launch a single general-purpose subagent with explicit model: "opus" (Rule 23 RULE-002 — deep test planning quality for Double-Loop TDD + TPP):
Agent(
subagent_type: "general-purpose",
model: "opus",
description: "Test Planning Assistant gathers context for test plan generation",
prompt: "<see the blockquote below>"
)
<!-- TELEMETRY: phase.end -->You are a Test Planning Assistant gathering context for test plan generation.
Read the template for required output format (RULE-007):
- Read template at
.claude/templates/_TEMPLATE-TEST-PLAN.mdfor required output format.- If the template file does NOT exist, log:
"Template not found, using inline format"and continue without it (RULE-012 — graceful fallback for projects without templates).Read these knowledge packs:
knowledge/testing/testing-philosophy.md— 8 test categories, fixture patterns, data uniqueness, async handling, real vs in-memory DB decisionsknowledge/testing/testing-conventions.md— {{LANGUAGE}}-specific test frameworks, naming conventions, directory structure, assertion librariesknowledge/architecture/architecture-principles.md— exception hierarchy, layer boundaries (unit vs integration), dependency directionRead testing knowledge pack for {{LANGUAGE}}-specific patterns:
- Read
knowledge/testing.mdfor {{LANGUAGE}}-specific test frameworks, conventions, and patternsRead the story:
{STORY_PATH}Extract: acceptance criteria, sub-tasks, business rules, dependencies.Scan existing code:
- List existing classes in target packages
- List existing test classes and patterns established
Return a structured context summary:
- Test categories applicable to this story (from the 8 categories in testing-philosophy)
- Naming convention:
[method]_[scenario]_[expected]pattern with {{LANGUAGE}}-specific format- Test frameworks and assertion libraries to use (from testing-conventions)
- Fixture pattern:
final class+private constructor+static methods, naminga{Entity}()- Acceptance criteria extracted from story (each becomes ≥1 test)
- Business rules extracted (each maps to parametrized tests)
- Exception types in scope (each needs error path test)
- Layer boundaries — which classes need unit vs integration tests
- Existing patterns found in current test codebase
- Contract tests applicable (if testing.contract_tests == true)
- Chaos tests applicable (if testing.chaos_tests == true)
- Template sections — if template was found, list the 8 mandatory sections to populate
Bash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh end x-test-plan Phase-1-KP-Read ok
Using the context returned by the subagent, generate a Double-Loop TDD test plan. Organize scenarios by implementation order (TPP), NOT by test category.
<!-- TELEMETRY: phase.start -->Bash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh start x-test-plan Phase-2-Acceptance-Tests
For each Gherkin scenario in the story, generate an acceptance test entry:
| Field | Description |
|-------|-------------|
| ID | AT-N (sequential) |
| Gherkin | Reference to the original scenario |
| Status | RED until all unit tests for this acceptance criteria complete |
| Components | List of classes/modules under test |
| Test Type | Integration, API, or E2E (depending on story scope) |
| Depends on | UT/IT IDs that must pass for this AT to go GREEN, or -- |
| Parallel | yes if independent of other ATs |
Bash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh end x-test-plan Phase-2-Acceptance-Tests ok
Bash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh start x-test-plan Phase-3-Unit-Tests-TPP
Generate unit test scenarios in strict TPP order. Each scenario represents one Red-Green-Refactor cycle.
{}→nil or nil→constantconstant→variableunconditional→conditionalscalar→collection, statement→recursion/iterationvalue→mutated valueFor each unit test entry, include:
| Field | Required | Description |
|-------|----------|-------------|
| ID | M | UT-N (sequential within TPP order) |
| Test | M | What to test (method + scenario + expected) |
| Implementation | O | Minimum code to pass this test |
| Transform | M | TPP transformation applied |
| TPP Level | M | 1-6 |
| Components | M | Classes/modules needed |
| Depends on | M | Previous test IDs that are prerequisites, or -- |
| Parallel | M | yes if independent of other tests at same level |
Position AFTER the unit tests of the components involved. Include only when multiple components interact (DB, HTTP, messaging).
| Field | Required | Description |
|-------|----------|-------------|
| ID | M | IT-N (sequential) |
| Test | M | What to test |
| Components | M | Interacting components |
| Depends on | M | UT IDs that must pass first |
| Parallel | M | yes/no |
When a story describes a purely CRUD operation without branching logic:
Bash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh end x-test-plan Phase-3-Unit-Tests-TPP ok
Bash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh start x-test-plan Phase-4-Report
| Class | Public Methods | Branches | Est. Tests | Line % | Branch % | |-------|---------------|----------|-----------|--------|----------| | [Name] | [count] | [count] | [count] | [%] | [%] |
Flag any class where estimated coverage < 95% line / 90% branch.
[method]_[scenario]_[expected]Bash command: $CLAUDE_PROJECT_DIR/.claude/hooks/telemetry-phase.sh end x-test-plan Phase-4-Report ok
Save to: plans/epic-XXXX/plans/tests-story-XXXX-YYYY.md (extract epic ID XXXX and story sequence YYYY from the story ID). Ensure directory exists: mkdir -p plans/epic-XXXX/plans.
Before writing the test plan file, prepend the YAML frontmatter block at the very top:
---
generated-by: x-test-plan@$(git rev-parse HEAD 2>/dev/null || echo "unknown")
generated-at: $(date -u +%Y-%m-%dT%H:%M:%SZ)
story-id: ${STORY_ID}
---
This frontmatter is required by audit-execution-integrity.sh Phase-1 validation (EPIC-0059, Rule 24).
Artifacts without this block fail the CI audit with EIE_EVIDENCE_MISSING.
# Test Plan — STORY-ID: [Title]
## Summary
- Acceptance tests: X (from Y Gherkin scenarios)
- Unit tests: ~Z (in TPP order)
- Integration tests: ~W
- Estimated line coverage: ~P%
- Estimated branch coverage: ~Q%
## Acceptance Tests (Outer Loop)
### AT-1: [Gherkin scenario name]
- **Gherkin**: [reference to story scenario]
- **Status**: RED until all unit tests complete
- **Components**: [list of components under test]
- **Acceptance Criteria**: [what must be true for this AT to pass]
- **Depends on**: UT-1, UT-2, ... (UTs that must pass)
- **Parallel**: yes/no
## Unit Tests (Inner Loop — TPP Order)
### UT-1: [degenerate case description] — TPP Level 1
- **Test**: [methodUnderTest]_[scenario]_[expectedBehavior]
- **Implementation**: [minimum code to pass]
- **Transform**: {}→nil
- **Components**: [class/module]
- **Depends on**: --
- **Parallel**: yes
### UT-2: [next case description] — TPP Level 2
- **Test**: [methodUnderTest]_[scenario]_[expectedBehavior]
- **Implementation**: [minimum code to pass]
- **Transform**: constant→variable
- **Components**: [class/module]
- **Depends on**: UT-1
- **Parallel**: no
...
## Integration Tests (Cross-Component)
### IT-1: [integration scenario]
- **Test**: [description]
- **Components**: [interacting components]
- **Depends on**: UT-3, UT-7
- **Parallel**: no
## Coverage Estimation
[table]
## Risks and Gaps
- [Hard-to-test scenarios]
- [Coverage gaps needing attention]
| Scenario | Action | |----------|--------| | No story ID provided | Prompt user for story identifier | | Story file not found | Abort with file-not-found message | | Existing plan is fresh (RULE-002) | Return existing plan, skip generation | | Template not found (RULE-012) | Log warning, use inline format, continue | | No Gherkin scenarios in story | Generate tests from acceptance criteria text | | No acceptance criteria found | Abort with warning, request story refinement |
When .claude/templates/_TEMPLATE-TEST-PLAN.md is not available (projects predating EPIC-0024):
"Template not found, using inline format"This ensures backward compatibility with projects that have not yet adopted template-based generation.
| Pack | Files | Purpose |
|------|-------|---------|
| testing | knowledge/testing/testing-philosophy.md | 8 test categories, fixture patterns, data uniqueness |
| testing | knowledge/testing/testing-conventions.md | {{LANGUAGE}}-specific test frameworks, naming, assertions |
| testing | knowledge/testing.md | {{LANGUAGE}}-specific test patterns |
| architecture | knowledge/architecture/architecture-principles.md | Exception hierarchy, layer boundaries |
| Skill | Relationship | Context |
|-------|-------------|---------|
| x-story-implement | called-by | Invoked during Phase 1B |
| x-task-implement | reads | Output consumed as TDD roadmap |
model: "opus" (Rule 23 RULE-002) for deep test planning qualityV2-gated: only runs when
SchemaVersionResolver.resolve(plans/epic-XXXX/execution-state.json) == V2. v1 epics: skip silently (Rule 19).
After writing tests-story-XXXX-YYYY.md, check the associated story's lifecycle status. The test plan, like the architecture plan, is a secondary writer — the primary transition Pendente → Planejada is owned by x-story-plan. When x-test-plan runs standalone (without x-story-plan), it promotes the story from Pendente to Planejada so the source artifact reflects that the test plan is in place.
Steps (end of test-plan generation, BEFORE the final commit):
Detect v2 via SchemaVersionResolver. If v1: skip.
Read current story status:
CURRENT=$(java -cp $CLAUDE_PROJECT_DIR/java/target/classes \
dev.iadev.adapter.inbound.cli.StatusFieldParserCli \
read plans/epic-XXXX/story-XXXX-YYYY.md)
If CURRENT == "Pendente" → write Planejada. Idempotent when already Planejada.
Stage and commit:
git add plans/epic-XXXX/story-XXXX-YYYY.md plans/epic-XXXX/plans/tests-story-XXXX-YYYY.md
Skill(skill: "x-git-commit", args: "docs(story-XXXX-YYYY): add test plan + update status to Planejada")
Fail-loud: non-zero CLI exit aborts the skill (RULE-046-08).
testing
Scaffolds a Helidon SE/MP service with routing, health, config, Dockerfile, and tests.
tools
Generates a Picocli @Command with subcommands, options, converters, and unit tests.
testing
Scaffolds a Micronaut service with @Controller, DI, health, Dockerfile, and tests.
testing
Scaffolds a Helidon SE/MP service with routing, health, config, Dockerfile, and tests.