Test Anti-Patterns
The Test Analyzer: Anti-Patterns agent is a specialized test analyzer focused on test anti-patterns. It finds structural patterns in tests that make them brittle, hard to maintain, or misleading — patterns that experienced developers know to avoid.
When to Use
Use this agent when:
- You need to identify tests accessing private methods or internal APIs
- You want to find deep mock chains that mirror internal implementation
- You're checking for oversized snapshots that are hard to review
- You need to refactor tests with more setup than assertions
- You're looking for God test objects used across many tests
How It Works
- Reads target tests - Examines test structure and patterns
- Identifies patterns - Looks for private access, deep mocking, large snapshots, setup ratios, and shared fixtures
- Assesses impact - Determines maintenance burden when code is refactored
- Reports findings - Generates findings with specific refactoring suggestions
Focus Areas
- Testing private methods directly: Accessing internal implementation via workarounds instead of testing through public API
- Deep mock chains: Mocking 3+ levels deep, mirroring internal implementation structure
- Oversized snapshots: Snapshot files > 500 lines, testing entire page output instead of specific elements
- Test setup longer than test: More lines of setup/mock configuration than actual assertions
- God test objects: Single fixture/factory that creates everything, used by all tests
Tools Available
This agent has access to: Read, Glob, Grep
Example Analysis
Given this test:
it('validates internal format', () => {
const service = new UserService();
// Accessing private method with @ts-ignore
// @ts-ignore
const result = service['_validateFormat']('test');
expect(result).toBe(true);
});The Anti-Patterns analyzer would identify:
Finding: Testing private method through bracket notation
Location: services/user.test.ts:42
Severity: MEDIUM
Confidence: HIGH
Category: Testing Privates
Issue: Test directly accesses private method _validateFormat using bracket notation and @ts-ignore. This test breaks if the method is renamed or refactored, and tests implementation details instead of behavior.
Maintenance Cost: When refactoring UserService internals, this test fails even if public API still works correctly. Tests private implementation, not public contract.
Remediation:
// ANTI-PATTERN: Tests private method
it('validates internal format', () => {
const service = new UserService();
// @ts-ignore
const result = service['_validateFormat']('test');
expect(result).toBe(true);
});
// BETTER: Test through public API
it('rejects invalid user data', () => {
const service = new UserService();
// Public method calls _validateFormat internally
expect(() => service.createUser({ name: 'invalid<script>' }))
.toThrow(ValidationError);
});
// BETTER: Export private function as separate, testable utility
// In service.ts
export function validateFormat(input: string): boolean {
// validation logic
}
// In test
import { validateFormat } from '../services/user';
it('validates format correctly', () => {
expect(validateFormat('test')).toBe(true);
});Best Practices
- Test behavior through public APIs, not private methods
- Keep mock chains shallow (1-2 levels max); if deeper, refactor code
- Keep snapshots small (<50 lines); use specific assertions instead
- Keep test setup and assertions balanced; if setup >> assertions, refactor
- Create specific factories per domain:
createTestUser(),createTestPayment() - Avoid God objects; use composable, focused factories
- When testing is hard (lots of setup, deep mocking), the code design likely needs improvement
- Document why complex setup is necessary
Output Format
For each potential issue, the agent provides:
- Location: Exact file path and line number
- Severity: CRITICAL (systemic brittleness), HIGH (significant burden), MEDIUM (friction), LOW (smell)
- Category: Testing Privates, Deep Mock Chain, Oversized Snapshot, Setup > Test, God Object, Redundant Assertions
- Code: Relevant test code snippet
- Issue: Clear explanation of the anti-pattern
- Maintenance Cost: How this affects test maintenance when code changes
- Remediation: Specific refactoring suggestion with code example
Example Usage
Task(
description: "Refactor test anti-patterns in payment service tests",
prompt: "Audit src/__tests__/payments.test.ts for deep mock chains, oversized snapshots, and God objects. Suggest refactored factory functions and simplified mocks.",
subagent_type: "agileflow-test-analyzer-patterns"
)Related Agents
test-analyzer-coverage- Coverage gap detectiontest-analyzer-fragility- Test flakiness detectiontest-analyzer-mocking- Mock quality analysistest-analyzer-assertions- Assertion strength analysistest-analyzer-structure- Test organization analysistest-analyzer-integration- Integration test gapstest-analyzer-maintenance- Test maintenance debttest-consensus- Test audit consensus coordinator