| name | validate-tests |
| description | Detects test anti-patterns based on behavior testing principles |
| triggers | ["validate tests","check tests"] |
| user-invocable | true |
| allowed-tools | ["Read","Write","Glob","Grep","Bash"] |
validate-tests -- Test Anti-Pattern Detection
Corresponding rule: testing.md
Purpose
Statically detect anti-patterns in test code based on behavior-driven testing principles (testing.md). Identify patterns that hurt maintainability, such as implementation-detail testing, excessive mocking, and shared global state.
Input
- Target: test files (
*.test.*, *.spec.*, test_*, *_test.*)
- Default search path: entire project. If CLAUDE.md specifies a test directory, that path takes precedence.
Validation Categories
1. Vague Test Names
Detect patterns where test names provide no clue to the cause of failure.
Search patterns:
test_\d+$ (names ending only in a number: test_1, test_2)
test_it_works
test_function
test_ok
test_success
it\(["']works["'] (JS/TS: it('works'))
it\(["']should work["']
test\(["']test["'] (JS/TS: test('test'))
Severity: WARN
2. Implementation-Detail Tests
Detect patterns that verify call count/existence of internal methods.
Search patterns:
.call_count
.called
.assert_called_with
.assert_called_once
.assert_called_once_with
.assert_any_call
.toHaveBeenCalledTimes (Jest)
.toHaveBeenCalledWith (Jest)
verify(.*).times( (Java Mockito)
Severity: WARN
3. Excessive Mocks
Detect patterns where a single test function uses 4 or more Mock objects.
Search patterns:
Mock() or mock.patch appears 4+ times in a single test function
jest.fn() or jest.mock appears 4+ times in a single test
@mock.patch decorators: 4+ on a single test function
Severity: WARN (when 4 or more)
4. Shared Global State
Detect patterns where test files create instances at module level, sharing state across tests.
Search patterns:
= new (instance creation) -- at the top level of a test file (outside functions/classes)
- Variables with
shared_ prefix
- Module-level
let declarations that are mutated by tests (JS/TS)
- Use of the
global keyword at the top level of a test file
Severity: WARN
5. DB Dependency in Unit Tests
Detect patterns where unit test files directly call DB connections/queries. Exclude integration test files whose names contain integration, e2e, or integ.
Search patterns:
db.query
db.execute
db.session
db.connect
prisma. (query methods)
mongoose.connect
connection.execute
pool.query
Exclusion condition: file name contains integration, e2e, or integ
Severity: WARN
Execution Logic
Glob to collect test files (*.test.*, *.spec.*, test_*, *_test.*)
- Categories 1, 2, 5:
Grep each pattern across all test files
- Category 3:
Read test files and tally Mock count per function
- Category 4:
Read test files and detect instance creation at module level (outside functions/classes)
- Group detected anti-patterns by category and output as a table
Mandatory Output: Test Validation Matrix
Output the matrix below before generating the final report. Do not proceed until every category has been scanned.
| Category | Status | Items Checked | Findings | Severity | Evidence |
|---|
| Vague Test Names | ? | ? | ? | WARN | {Glob/Grep, files, pattern} |
| Implementation-Detail Tests | ? | ? | ? | WARN | {Glob/Grep, files, pattern} |
| Excessive Mocks | ? | ? | ? | WARN | {Read, scanned files} |
| Shared Global State | ? | ? | ? | WARN | {Read, scanned files} |
| DB Dependency | ? | ? | ? | WARN | {Grep, files, pattern} |
Status values: PASS (verification complete, no issues), NOT_APPLICABLE (no test files), SKIPPED (plugin issue), SHALLOW (partial scan)
Pre-Output Checklist (Mandatory Before Final Output)
Check every item before writing the report. If any item is unchecked, go back and complete it.
Schema Compliance Check (Mandatory Before Saving to .ww-w-ai/)
Before writing to .ww-w-ai/devtools/validate-tests/, verify the JSON output:
Output
Generate the validation report in the user's conversation language.
Output detection results as a Markdown table in this format:
===== Test Validation Report =====
| File:Line | Type | Description |
|-----------|------|-------------|
| `src/services/auth.test.ts:15` | Vague Name | `test_1` -- cannot identify failure cause |
| `src/services/order.test.ts:42` | Implementation Detail | `.assert_called_once_with` -- internal-call verification |
| `src/services/payment.test.ts:20` | Excessive Mocks | 6 Mocks used -- design review needed |
| `test_user.py:5` | Global State | `shared_cart = Cart()` -- state shared across tests |
| `src/utils/calc.test.ts:30` | DB Dependency | Direct `db.query` call -- unit test depends on DB |
Total anti-patterns: {N}
Vague Names: {A}
Implementation Detail: {B}
Excessive Mocks: {C}
Global State: {D}
DB Dependency: {E}
===============================
When no anti-patterns are found:
===== Test Validation Report =====
No anti-patterns.
===============================
Output Persistence
After generating the test validation report, save results to .ww-w-ai/devtools/validate-tests/:
- Create
.ww-w-ai/devtools/validate-tests/ if missing
- Write
latest.json -- structured result following templates/schema.json
- Write
latest.md -- human-readable report following templates/report.template.md
- Archive to
history/ -- copy latest.json to .ww-w-ai/devtools/validate-tests/history/{timestamp}.json
latest.md is generated in the user's conversation language. JSON field names stay in English regardless of language.
The JSON output enables machine-parseable history tracking and cross-run comparison.
The history/ directory preserves previous executions for trend analysis.
Permission Rationale
- Write: Exclusively for .ww-w-ai/ output persistence. No project source modification.
- Bash: Exclusively for read-only git/system queries. No file modifications.
Notes
- Bash is permitted for directory creation (
mkdir -p .ww-w-ai/devtools/validate-tests/history). The validation itself is read-only and does not modify project files.
- "Change-detection tests" in legacy code are temporarily allowed per testing.md exceptions. If the file or directory contains
legacy, migration, or compat, annotate the result with "(legacy allowance)."
- Implementation-detail test detection (Category 2) may yield false positives.
.toHaveBeenCalledWith can also be used for external-dependency verification (e.g., API calls), so results are presented as advisory.
- Excessive-Mocks judgment (Category 3) is performed per function. Mocks set up in
beforeEach/setUp are distributed and tallied against each test.
Spec Reference
For detailed validation criteria, evidence tables, and examples:
- Corresponding rule spec:
../../docs/specs/testing.md