From test-writing
Generates and validates PHPUnit unit tests for PHP classes with review-fix cycles using phpunit_run, phpstan_analyze, and ecs tools. For Shopware 6 unit test coverage.
npx claudepluginhub shopwarelabs/ai-coding-tools --plugin test-writingThis skill is limited to using the following tools:
Orchestrates the complete workflow for generating and reviewing Shopware 6 unit tests.
Generates design tokens/docs from CSS/Tailwind/styled-components codebases, audits visual consistency across 10 dimensions, detects AI slop in UI.
Records polished WebM UI demo videos of web apps using Playwright with cursor overlay, natural pacing, and three-phase scripting. Activates for demo, walkthrough, screen recording, or tutorial requests.
Delivers idiomatic Kotlin patterns for null safety, immutability, sealed classes, coroutines, Flows, extensions, DSL builders, and Gradle DSL. Use when writing, reviewing, refactoring, or designing Kotlin code.
Orchestrates the complete workflow for generating and reviewing Shopware 6 unit tests.
Execute immediately. Report work AFTER completion, never before.
Process the complete workflow (Generate → Coverage Exclusion → Review → Fix → Report) for that one file.
Process files sequentially — one file at a time:
FOR EACH source file:
1. Generate test (wait for completion)
2. Review test (wait for completion)
3. Fix loop if needed (wait for completion)
4. Mark file complete
5. Collapse intermediate state to compact summary
THEN proceed to next file
After each file completes all phases, collapse intermediate state (generation details, review iterations, fix attempts) to a compact summary before proceeding to the next file. This prevents context growth on multi-file runs.
Never modify:
src/** — Source codetests/integration/** — Integration tests (out of scope)tests/unit/**Conditional modification (user confirmation required):
phpunit.xml.dist — Only adding <file> entries to <exclude> section, only during Phase 2Identify the source class requiring tests
Invoke generation skill:
Skill(test-writing:phpunit-unit-test-generation) with source: {source_class_path}
Parse response for:
test_path: Location of generated test filestatus: SUCCESS | PARTIAL | FAILED | SKIPPEDcategory: A | B | C | D | E (test complexity category)skip_type: coverage_excluded | no_logic (only when SKIPPED)Decision:
skip_type: coverage_excluded → Report reason to user, end workflowskip_type: no_logic → Proceed to Phase 2 (Coverage Exclusion Offer)Update workflow state on SUCCESS/PARTIAL:
TodoWrite([
{content: "Generate unit tests", status: "completed", activeForm: "Generating unit tests"},
{content: "Review unit tests", status: "in_progress", activeForm: "Reviewing unit tests"}
])
Entry condition: Generator returned SKIPPED with skip_type: no_logic.
Source files with no testable logic still appear as 0% in coverage reports unless excluded. This phase offers to add them to phpunit.xml.dist so coverage reports only show files that actually need testing.
phpunit.xml.dist from the project root (fallback: phpunit.xml)<exclude> section within <coverage>/<source> (or <source>){source_path} was skipped — no testable logic detected ({reason}).
Add it to phpunit.xml.dist coverage exclusions so it doesn't show as uncovered?
Options: "Yes, exclude from coverage" / "No, skip"<exclude> section exists → Use Edit to add <file>{relative_path}</file> before </exclude><exclude> section → Use Edit to insert <exclude><file>{relative_path}</file></exclude> before </source>coverage_excluded: truecoverage_excluded: falseDo NOT prompt per file. Instead, collect all skip_type: no_logic files across the batch. After all files complete their workflow phases, present a single batch prompt:
X files were skipped — no testable logic detected.
Add them to phpunit.xml.dist coverage exclusions?
- src/Core/Content/Product/ProductEntity.php (Pure accessor)
- src/Core/Content/Category/CategoryCollection.php (Simple collection)
Options: "Yes, exclude all from coverage" / "No, skip"
If approved, add all <file> entries in a single Edit operation.
MUST execute when generator returned SUCCESS or PARTIAL. Never skip.
Invoke reviewing skill:
Agent(
agent: "test-writing:test-reviewer",
prompt: "Invoke Skill(test-writing:phpunit-unit-test-reviewing) for {test_path}. Return the structured report."
)
Parse response:
status: PASS | NEEDS_ATTENTION | ISSUES_FOUND | FAILEDerrors: Remaining must-fix rules (mandatory compliance failures)warnings: Remaining should-fix rules (optional improvements)Decision:
| Status | Action |
|---|---|
| PASS | Proceed to Phase 6 (Final Report) with status COMPLIANT |
| NEEDS_ATTENTION | Proceed to Phase 4 (Fix Loop) for warnings, then Phase 5 for any unresolved |
| ISSUES_FOUND | Proceed to Phase 4 (Fix Loop) |
| FAILED | Report failure reason, end workflow |
Entry condition: Review returned ISSUES_FOUND (has must-fix errors).
The loop continues until ALL errors are resolved — both tool validation errors (PHPStan/PHPUnit/ECS) AND semantic review errors (must-fix rules from reviewing skill).
FOR iteration 1 to 4:
1. Apply ALL fixes from review report errors (Edit tool)
2. Run ECS fix for code style
3. Run PHPStan to validate (fix any new errors)
4. Run PHPUnit to verify tests pass
5. Re-invoke reviewing skill to check for remaining issues
6. Track issue history for oscillation
7. Check exit conditions (PASS = 0 errors from review AND tools)
↓
Return final result
For each must-fix rule with suggested fix from the review report:
{rule_id, location, attempted: true, applied: true/false, reason: null}Priority order when fixes conflict:
mcp__plugin_dev-tooling_php-tooling__ecs_fix {
paths: ["{test_path}"]
}
mcp__plugin_dev-tooling_php-tooling__phpstan_analyze {
paths: ["{test_path}"],
error_format: "json"
}
If PHPStan errors, attempt to fix before continuing.
mcp__plugin_dev-tooling_php-tooling__phpunit_run {
paths: ["{test_path}"],
output_format: "result-only"
}
If tests fail, re-run without output_format to capture failure details, then continue to review.
Agent(
agent: "test-writing:test-reviewer",
prompt: "Invoke Skill(test-writing:phpunit-unit-test-reviewing) for {test_path}. Return the structured report."
)
Spawns test-reviewer agent → returns updated report with errors/warnings.
Maintain issue history for oscillation detection:
issue_history:
- iteration: 1
issues: ["{rule_id}:45", "{rule_id}:67"]
- iteration: 2
issues: ["{rule_id}:12"]
- iteration: 3
issues: ["{rule_id}:45"] # same rule:line returned — oscillation!
Oscillation Detection:
{rule_id}:{line_number} per iteration| Condition | Action |
|---|---|
| Review returns 0 errors AND tools pass | Exit with status: PASS |
| Oscillation detected | Handle per references/oscillation-handling.md |
| Same errors 2x consecutively | Exit as stuck loop with remaining errors |
| Iteration 4 reached with errors remaining | Exit with status: ISSUES_FOUND |
PASS Criteria (all must be met):
ISSUES_FOUND means must-fix rules could not be resolved within 4 iterations — these are mandatory compliance failures.
If warnings remain after error correction:
Provide comprehensive summary. See references/report-formats.md for templates.
Include:
If skill invocation fails:
Workflow Aborted
Required skill `[name]` could not be invoked.
Please ensure the plugin is properly configured and try again.
Do not attempt to manually generate or review tests if skills fail.
If test-writing:phpunit-unit-test-generation returns FAILED:
If SKIPPED with skip_type: coverage_excluded:
If SKIPPED with skip_type: no_logic:
Common failure reasons:
src/ directoryIf fix loop exits with ISSUES_FOUND after max iterations:
Common failure reasons: