Detect test smells, overmocking, flaky tests, and coverage issues. Analyze test effectiveness, maintainability, and reliability. Use when reviewing tests or improving test quality.
View on GitHubsecondsky/claude-skills
test-quality-analysis
January 24, 2026
Select agents to install to:
npx add-skill https://github.com/secondsky/claude-skills/blob/main/plugins/test-quality-analysis/skills/test-quality-analysis/SKILL.md -a claude-code --skill test-quality-analysisInstallation paths:
.claude/skills/test-quality-analysis/# 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.
```typescript
// ❌ BAD: Overmocked
test('calculate total', () => {
const mockAdd = vi.fn(() => 10)
const mockMultiply = vi.fn(() => 20)
// Testing implementation, not behavior
})
// ✅ GOOD: Mock only external dependencies
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.
```typescript
// ❌ BAD: Tests implementation details
await page.locator('.form-container > div:nth-child(2) > button').click()
// ✅ GOOD: Semantic selector
await page.getByRole('button', { name: 'Submit' }).click()
```
### Flaky Tests
**Problem**: Tests pass or fail non-deterministically.
```typescript
// ❌ BAD: Race condition
test('loads data', async () => {
fetchData()
await new Promise(resolve => setTimeout(resolve, 1000))
expect(data).toBeDefined()
})
// ✅ GOOD: Proper async handling
test('loads data', async () => {
const data = await fetchData()
expect(data).toBeDefined()
})
```
### Poor Assertions
```typescript
// ❌ BAD: Weak assertion
test('returns users', async () => {
const users = await getUsers()
expect(users).toBeDefined() // Too vague!
})
/