VCP Review Tests
Review test files for quality anti-patterns against VCP testing standards.
Step 1: Resolve Config
- Read
.vcp/config.json from the project root. Extract the pluginRoot field.
- If
.vcp/config.json does not exist or pluginRoot is missing: Stop and tell the user: "No VCP configuration found. Run /vcp-init to configure VCP for this project."
- Validate
pluginRoot: The path must be absolute, contain /.claude/ (or \.claude\ on Windows) as a path segment, and contain only safe path characters (letters, digits, /, \, -, _, ., :, and spaces). Reject any path with shell metacharacters (;, &, |, $, `, (, ), {, }, <, >, !, ~, #, *, ?, [, ], ', "). If validation fails, stop and tell the user: "Invalid pluginRoot — must be within ~/.claude/ and contain no shell metacharacters. Run /vcp-init to fix." Also verify the file <pluginRoot>/lib/vcp-context-core.ts exists using Glob. If it does not exist, stop and tell the user: "pluginRoot points to an invalid VCP installation. Run /vcp-init to fix."
- Run the config resolution script via Bash:
bun "<pluginRoot>/lib/resolve-config.ts" "<project-root>"
- Parse the JSON output. It contains:
applicableStandards, ignoredRules, severity, exclude.
Step 2: Fetch Applicable Standards
From the applicableStandards array in the resolved config, keep only the entry where:
Use WebFetch to fetch its content from:
{entry.url}
Extract the Rules section and the Patterns section (for anti-pattern reference).
Step 4: Find and Review Test Files
Target path: $ARGUMENTS if provided. If not provided, scan the entire project.
Use Glob to find test files matching these patterns (exclude patterns from exclude in the resolved config):
**/*.test.* (JavaScript/TypeScript)
**/*.spec.* (JavaScript/TypeScript)
**/test_*.* (Python)
**/__tests__/** (JavaScript/TypeScript)
**/*_test.go (Go)
**/*Test.java (Java)
**/*_test.rb (Ruby)
**/*_spec.rb (Ruby/RSpec)
**/*_test.rs (Rust)
Read each test file and check for these 8 anti-patterns:
Anti-Pattern Checks
Tautological tests — Tests that assert the code does what it does (generated by reading implementation and asserting same logic). Test verifies its own setup, not real behavior. (Rules 3, 11)
Over-mocking — More than 3 mock/stub setups in a single test, especially mocking internal classes/services that should be tested through. (Rules 4, 6)
Mock-only assertions — Test assertions only verify mock calls (.assert_called_once(), .toHaveBeenCalledWith()) with no assertions on actual return values, state changes, or side effects. (Rule 5)
Missing edge cases — Happy path tested but no tests for: null/undefined/empty inputs, boundary values, error conditions, special characters. (Rule 7)
Missing error paths — Operations that can fail (network, file I/O, parsing, validation) have no failure-case tests. (Rule 8)
Implementation coupling — Tests assert on internal method calls, private state, or execution order rather than observable outcomes. Tests that would break on refactoring without behavior change. (Rule 1)
Non-deterministic tests — Tests depending on current time, random values, network availability, or uncontrolled filesystem state. (Rule 10)
Shared mutable state — Tests that modify shared variables, global state, or class-level fixtures without reset. Tests that depend on execution order. (Rule 9)
Step 5: Report Findings
Output findings per file with a quality rating, then detail findings.
Before outputting findings, remove any that match an entry in the ignoredRules array from the resolved config. If "standard-id/rule-N" is in the list, suppress that specific rule's findings. (Standard-level ignores are already applied by the config resolution script.) After filtering, if any findings were suppressed, append a line: **Suppressed:** X finding(s) by ignore config.
Use this format:
### VCP Test Review
**Standard:** core-testing (12 rules)
**Test files found:** N files
#### Summary
| File | Rating | Issues |
|------|--------|--------|
| tests/test_orders.py | GOOD | 0 |
| tests/test_payments.py | NEEDS WORK | 3 (over-mocking, mock-only assertions, missing edge cases) |
| tests/test_auth.py | REWRITE | 5 (tautological, over-mocking, implementation coupling, ...) |
#### Findings
##### tests/test_payments.py — NEEDS WORK
- **Over-mocking** (Rule 4) — `test_process_payment` at line 42
- **Issue:** 5 mocks set up including internal `PriceCalculator` and `OrderValidator`
- **Fix:** Only mock the external payment gateway. Use real `PriceCalculator` and `OrderValidator`.
- **Mock-only assertions** (Rule 5) — `test_process_payment` at line 55
- **Issue:** Only asserts `mock_gateway.charge.assert_called_once()` — no assertion on the returned order total
- **Fix:** Assert on the return value: `assert result.total == expected_total`
- **Missing edge cases** (Rule 7) — `test_process_payment` has no tests for:
- Zero-amount orders
- Negative amounts
- Currency edge cases
...
Rating criteria:
- GOOD — No anti-patterns found
- NEEDS WORK — 1-3 anti-patterns found. Tests have value but need improvement.
- REWRITE — 4+ anti-patterns found, or tautological tests (tests that validate nothing real). Tests provide false confidence and should be rewritten.
If no test files found: "No test files found in [path]. Nothing to review."
If all tests pass: "All N test files pass quality review. No anti-patterns found."
1---2name: vcp-review-tests3description: Review test quality against VCP testing standards. Checks for tautological tests, over-mocking, missing edge cases, and other anti-patterns.4---5
6# VCP Review Tests
7
8Review test files for quality anti-patterns against VCP testing standards.
9
10## Step 1: Resolve Config
11
121. Read `.vcp/config.json` from the project root. Extract the `pluginRoot` field.
132. **If `.vcp/config.json` does not exist or `pluginRoot` is missing:** Stop and tell the user: "No VCP configuration found. Run `/vcp-init` to configure VCP for this project."
143. **Validate `pluginRoot`:** The path must be absolute, contain `/.claude/` (or `\.claude\` on Windows) as a path segment, and contain only safe path characters (letters, digits, `/`, `\`, `-`, `_`, `.`, `:`, and spaces). Reject any path with shell metacharacters (`;`, `&`, `|`, `$`, `` ` ``, `(`, `)`, `{`, `}`, `<`, `>`, `!`, `~`, `#`, `*`, `?`, `[`, `]`, `'`, `"`). If validation fails, stop and tell the user: "Invalid pluginRoot — must be within ~/.claude/ and contain no shell metacharacters. Run `/vcp-init` to fix." Also verify the file `<pluginRoot>/lib/vcp-context-core.ts` exists using Glob. If it does not exist, stop and tell the user: "pluginRoot points to an invalid VCP installation. Run `/vcp-init` to fix."
154. Run the config resolution script via Bash:
16 ```bash
17 bun "<pluginRoot>/lib/resolve-config.ts" "<project-root>"
18 ```
195. Parse the JSON output. It contains: `applicableStandards`, `ignoredRules`, `severity`, `exclude`.
20
21## Step 2: Fetch Applicable Standards
22
23From the `applicableStandards` array in the resolved config, keep only the entry where:
24- `id` is `core-testing`
25
26Use WebFetch to fetch its content from:
27```
28{entry.url}
29```
30
31Extract the **Rules** section and the **Patterns** section (for anti-pattern reference).
32
33## Step 4: Find and Review Test Files
34
35**Target path:** `$ARGUMENTS` if provided. If not provided, scan the entire project.
36
371. Use Glob to find test files matching these patterns (exclude patterns from `exclude` in the resolved config):
38 - `**/*.test.*` (JavaScript/TypeScript)
39 - `**/*.spec.*` (JavaScript/TypeScript)
40 - `**/test_*.*` (Python)
41 - `**/__tests__/**` (JavaScript/TypeScript)
42 - `**/*_test.go` (Go)
43 - `**/*Test.java` (Java)
44 - `**/*_test.rb` (Ruby)
45 - `**/*_spec.rb` (Ruby/RSpec)
46 - `**/*_test.rs` (Rust)
47
482. Read each test file and check for these 8 anti-patterns:
49
50### Anti-Pattern Checks
51
521. **Tautological tests** — Tests that assert the code does what it does (generated by reading implementation and asserting same logic). Test verifies its own setup, not real behavior. (Rules 3, 11)
53
542. **Over-mocking** — More than 3 mock/stub setups in a single test, especially mocking internal classes/services that should be tested through. (Rules 4, 6)
55
563. **Mock-only assertions** — Test assertions only verify mock calls (`.assert_called_once()`, `.toHaveBeenCalledWith()`) with no assertions on actual return values, state changes, or side effects. (Rule 5)
57
584. **Missing edge cases** — Happy path tested but no tests for: null/undefined/empty inputs, boundary values, error conditions, special characters. (Rule 7)
59
605. **Missing error paths** — Operations that can fail (network, file I/O, parsing, validation) have no failure-case tests. (Rule 8)
61
626. **Implementation coupling** — Tests assert on internal method calls, private state, or execution order rather than observable outcomes. Tests that would break on refactoring without behavior change. (Rule 1)
63
647. **Non-deterministic tests** — Tests depending on current time, random values, network availability, or uncontrolled filesystem state. (Rule 10)
65
668. **Shared mutable state** — Tests that modify shared variables, global state, or class-level fixtures without reset. Tests that depend on execution order. (Rule 9)
67
68## Step 5: Report Findings
69
70Output findings per file with a quality rating, then detail findings.
71
72Before outputting findings, remove any that match an entry in the `ignoredRules` array from the resolved config. If `"standard-id/rule-N"` is in the list, suppress that specific rule's findings. (Standard-level ignores are already applied by the config resolution script.) After filtering, if any findings were suppressed, append a line: `**Suppressed:** X finding(s) by ignore config.`
73
74Use this format:
75
76```
77### VCP Test Review
78
79**Standard:** core-testing (12 rules)
80**Test files found:** N files
81
82#### Summary
83
84| File | Rating | Issues |
85|------|--------|--------|
86| tests/test_orders.py | GOOD | 0 |
87| tests/test_payments.py | NEEDS WORK | 3 (over-mocking, mock-only assertions, missing edge cases) |
88| tests/test_auth.py | REWRITE | 5 (tautological, over-mocking, implementation coupling, ...) |
89
90#### Findings
91
92##### tests/test_payments.py — NEEDS WORK
93
94- **Over-mocking** (Rule 4) — `test_process_payment` at line 42
95 - **Issue:** 5 mocks set up including internal `PriceCalculator` and `OrderValidator`
96 - **Fix:** Only mock the external payment gateway. Use real `PriceCalculator` and `OrderValidator`.
97
98- **Mock-only assertions** (Rule 5) — `test_process_payment` at line 55
99 - **Issue:** Only asserts `mock_gateway.charge.assert_called_once()` — no assertion on the returned order total
100 - **Fix:** Assert on the return value: `assert result.total == expected_total`
101
102- **Missing edge cases** (Rule 7) — `test_process_payment` has no tests for:
103 - Zero-amount orders
104 - Negative amounts
105 - Currency edge cases
106
107...
108```
109
110Rating criteria:
111- **GOOD** — No anti-patterns found
112- **NEEDS WORK** — 1-3 anti-patterns found. Tests have value but need improvement.
113- **REWRITE** — 4+ anti-patterns found, or tautological tests (tests that validate nothing real). Tests provide false confidence and should be rewritten.
114
115If no test files found: **"No test files found in [path]. Nothing to review."**
116If all tests pass: **"All N test files pass quality review. No anti-patterns found."**