| name | test-quality-analysis |
| description | Detect test smells, overmocking, flaky tests, and coverage issues. Analyze test effectiveness, maintainability, and reliability. Use when reviewing tests or improving test quality. |
| allowed-tools | Bash, Read, Edit, Write, Grep, Glob, TodoWrite |
| license | MIT |
Test Quality Analysis
Expert knowledge for analyzing and improving test quality - detecting test smells, overmocking, insufficient coverage, and testing anti-patterns.
Core Dimensions
- Correctness: Tests verify the right behavior
- Reliability: Tests are deterministic, not flaky
- Maintainability: Tests are easy to understand
- Performance: Tests run quickly
- Coverage: Tests cover critical code paths
- Isolation: Tests don't depend on external state
Test Smells
Overmocking
Problem: Mocking too many dependencies makes tests fragile.
test('calculate total', () => {
const mockAdd = vi.fn(() => 10)
const mockMultiply = vi.fn(() => 20)
})
test('calculate order total', () => {
const mockPricingAPI = vi.fn(() => ({ tax: 0.1 }))
const total = calculateTotal(order, mockPricingAPI)
expect(total).toBe(38)
})
Detection: More than 3-4 mocks, mocking pure functions, complex mock setup.
Fix: Mock only I/O boundaries (APIs, databases, filesystem).
Fragile Tests
Problem: Tests break with unrelated code changes.
await page.locator('.form-container > div:nth-child(2) > button').click()
await page.getByRole('button', { name: 'Submit' }).click()
Flaky Tests
Problem: Tests pass or fail non-deterministically.
test('loads data', async () => {
fetchData()
await new Promise(resolve => setTimeout(resolve, 1000))
expect(data).toBeDefined()
})
test('loads data', async () => {
const data = await fetchData()
expect(data).toBeDefined()
})
Poor Assertions
test('returns users', async () => {
const users = await getUsers()
expect(users).toBeDefined()
})
test('creates user with correct attributes', async () => {
const user = await createUser({ name: 'John' })
expect(user).toMatchObject({
id: expect.any(Number),
name: 'John',
})
})
Analysis Tools
bun test --coverage
open coverage/index.html
bun test --coverage --coverage.thresholds.lines=80
uv run pytest --cov --cov-report=html
open htmlcov/index.html
Best Practices Checklist
Unit Test Quality (FIRST)
Mock Guidelines
Coverage Goals
Test Structure (AAA Pattern)
test('user registration', async () => {
const userData = { email: 'user@example.com' }
const user = await registerUser(userData)
expect(user.email).toBe('user@example.com')
})
Code Review Checklist
Common Anti-Patterns
Testing Implementation Details
const spy = vi.spyOn(Math, 'sqrt')
calculateDistance()
expect(spy).toHaveBeenCalled()
const distance = calculateDistance({ x: 0, y: 0 }, { x: 3, y: 4 })
expect(distance).toBe(5)
Mocking Too Much
const mockAdd = vi.fn((a, b) => a + b)
import { add } from './utils'
const mockPaymentGateway = vi.fn()
See Also
vitest-testing - TypeScript/JavaScript testing
playwright-testing - E2E testing
mutation-testing - Validate test effectiveness