Test Maintenance
The Test Analyzer: Test Maintenance agent is a specialized test analyzer focused on test maintenance debt. It finds dead tests, outdated assertions, and tests that pass for the wrong reasons — creating a false sense of security while the test suite rots.
When to Use
Use this agent when:
- You need to identify dead or skipped tests hiding coverage gaps
- You want to find outdated assertions checking removed features
- You're looking for tests passing for wrong reasons (mock returning hardcoded values)
- You need to clean up commented-out tests
- You want to identify unused test utilities and fixtures
How It Works
- Reads target tests - Examines test files for maintenance issues
- Identifies patterns - Looks for skipped/commented tests, outdated assertions, mock setup issues, and unused utilities
- Assesses impact - Determines how long tests have been stale and what coverage they hide
- Reports findings - Generates findings with cleanup and remediation steps
Focus Areas
- Dead tests: Commented out, always skipped (
.skip/xit/xdescribe), or disabled by condition - Outdated assertions: Tests asserting removed behavior, checking deprecated fields, or verifying old API shape
- Tests passing for wrong reasons: Tests that pass due to mock setup, not because code works correctly
- Unused test utilities: Helper functions, fixtures, factories that are no longer referenced
- Stale snapshots: Snapshot files that don't match current component output (auto-updated without review)
Tools Available
This agent has access to: Read, Glob, Grep
Example Analysis
Given this test file:
describe.skip('PaymentService', () => {
// Disabled 6 months ago, never re-enabled
it('processes refund', () => { ... });
it('handles failed refund', () => { ... });
it('sends refund notification', () => { ... });
});
it('returns user data', async () => {
const result = await getUser(1);
expect(result.firstName).toBeDefined(); // Field renamed to 'name' months ago
expect(result.lastName).toBeDefined(); // Field removed entirely
// Test still passes because mock returns old shape
});The Maintenance analyzer would identify:
Finding 1: Dead tests hiding coverage gaps
Location: payments.test.ts:5
Severity: HIGH
Confidence: HIGH
Category: Dead Test
Issue: Entire PaymentService test suite (3 tests) has been skipped with no clear reason. Refund functionality is completely untested, yet no failing tests indicate this gap.
Staleness Indicator: Skipped 6 months ago, no JIRA ticket or clear reason documented.
Remediation:
// Option 1: Re-enable and fix tests
describe('PaymentService', () => {
it('processes refund', () => { ... });
// Fix any broken tests, verify they pass
});
// Option 2: Document why skipped with ticket reference
describe.skip('PaymentService', () => {
// TODO(TICKET-123): Re-enable after payment API redesign
// Expected to be fixed by end of Q1 2024
it('processes refund', () => { ... });
});
// Option 3: Remove tests if feature no longer exists
// (if refunds were removed, delete entire describe block)Finding 2: Outdated assertions checking removed fields
Location: users.test.ts:28
Severity: MEDIUM
Confidence: HIGH
Category: Outdated Assertion
Issue: Test asserts on firstName and lastName fields that no longer exist in the user object. Test passes because mock returns old shape, giving false confidence that user retrieval works correctly.
Remediation:
// OUTDATED: Checking removed fields
it('returns user data', async () => {
const result = await getUser(1);
expect(result.firstName).toBeDefined();
expect(result.lastName).toBeDefined();
});
// UPDATED: Check current fields
it('returns user data', async () => {
const result = await getUser(1);
expect(result.name).toBeDefined();
expect(result.email).toBeDefined();
expect(result).toEqual({
id: 1,
name: 'Test User',
email: 'test@test.com'
});
});Best Practices
- Remove dead tests immediately; don't let them accumulate
- If skipping a test, document the reason and expected fix date with ticket reference
- When refactoring code, update all corresponding test assertions
- Regularly audit test suite for
describe.skip,it.skip, commented tests - Use grep to find unused test utilities
- Review snapshot changes carefully; don't auto-update without reviewing
- For async tests, always use
awaiton async operations to catch rejections - Document why test utilities exist if they're not obvious from names
Output Format
For each potential issue, the agent provides:
- Location: Exact file path and line number
- Severity: CRITICAL (false pass), HIGH (dead tests hiding gaps), MEDIUM (outdated), LOW (minor cleanup)
- Category: Dead Test, Outdated Assertion, False Pass, Unused Utility, Stale Snapshot, Missing Await
- Code: Relevant test code snippet
- Issue: Clear explanation of the maintenance problem
- Staleness Indicator: How long this has been dead/outdated
- Remediation: Fix: update, remove, or restore the test
Example Usage
Task(
description: "Clean up test maintenance debt",
prompt: "Audit src/__tests__/ for skipped tests, commented code, outdated assertions, and unused fixtures. Report what should be re-enabled, updated, or deleted.",
subagent_type: "agileflow-test-analyzer-maintenance"
)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-patterns- Test anti-pattern detectiontest-consensus- Test audit consensus coordinator