mcpField
T
test-quality-analysis

test-quality-analysis

github.com/laurigatesTesting & quality5939 installsUpdated 2d ago
Repository

About test-quality-analysis

A skill for developers reviewing and improving test suites. It covers test smells, overmocking, flaky tests, coverage gaps, and assertions, with analysis commands for TypeScript, JavaScript, and Python.

Key features

  1. 01Identifies common test smells
  2. 02Analyzes overmocking and flaky tests
  3. 03Checks coverage and test gaps
  4. 04Evaluates assertions and isolation
  5. 05Provides TS, JS, and Python commands

Use cases

  1. 01Review test suite maintainability
  2. 02Locate tests causing intermittent failures
  3. 03Find coverage gaps in critical paths

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/laurigates/claude-plugins --skill test-quality-analysis

After installing, type/test-quality-analysisin Claude Code to confirm it loaded.

Bundled filesREFERENCE.md

Details

From the project README

Test Quality Analysis

Expert knowledge for analyzing and improving test quality - detecting test smells, overmocking, insufficient coverage, and other testing anti-patterns.

When to Use This Skill

Use this skill when...Use another skill instead when...
Reviewing test quality and smellsWriting new unit tests (use vitest-testing)
Detecting overmocking or flaky testsSetting up E2E tests (use playwright-testing)
Analyzing test coverage gapsValidating tests via mutation (use mutation-testing)
Improving test maintainabilityGenerating test data (use property-based-testing)
Auditing test suites for anti-patternsWriting Python tests (use python-testing)

Core Expertise

Test Quality Dimensions

  • Correctness: Tests verify the right behavior
  • Reliability: Tests are deterministic and not flaky
  • Maintainability: Tests are easy to understand and modify
  • Performance: Tests run quickly
  • Coverage: Tests cover critical code paths
  • Isolation: Tests don't depend on external state

Test Smells - Quick Reference

SmellSymptomFix
Overmocking3+ mocks per test; mocking pure functionsMock only I/O boundaries; use real implementations
Fragile testsBreak on refactor without behavior changeTest public APIs; use semantic selectors
Flaky testsNon-deterministic pass/failProper async/await; mock time; ensure isolation
Test duplicationCopy-pasted setup across testsExtract to beforeEach(), fixtures, helpers
Slow testsSuite > 10s for unit testsbeforeAll() for expensive setup; parallelize
Poor assertionstoBeDefined(), no assertions, mock-only assertionsSpecific matchers; assert outputs and state
Insufficient coverageCritical paths untested80%+ on business logic; test error paths and boundaries

Analysis Tools

TypeScript/JavaScript
vitest --coverage                              # Coverage report
vitest --coverage --coverage.thresholds.lines=80  # Threshold check
vitest --reporter=verbose                      # Find slow tests
Python
uv run pytest --cov --cov-report=term-missing  # Coverage with missing lines
uv run pytest --cov --cov-fail-under=80        # Threshold check
uv run pytest --durations=10                   # Find slow tests

Key Anti-Patterns

Testing Implementation vs Behavior
// BAD: Testing how
test('uses correct algorithm', () => {
  const spy = vi.spyOn(Math, 'sqrt')
  calculateDistance({ x: 0, y: 0 }, { x: 3, y: 4 })
  expect(spy).toHaveBeenCalled()
})

// GOOD: Testing what
test('calculates distance correctly', () => {
  const distance = calculateDistance({ x: 0, y: 0 }, { x: 3, y: 4 })
  expect(distance).toBe(5)
})
Weak Assertions
// BAD
expect(users).toBeDefined()     // Too vague
expect(mockAPI).toHaveBeenCalled() // Testing mock, not behavior

// GOOD
expect(user).toMatchObject({
  id: expect.any(Number),
  name: 'John',
  email: '[email protected]',
})
Missing Coverage
// BAD: Only tests happy path
test('applies discount', () => {
  expect(calculateDiscount(100, 'SAVE20')).toBe(80)
})

// GOOD: Tests all paths
describe('calculateDiscount', () => {
  it('applies SAVE20', () => expect(calculateDiscount(100, 'SAVE20')).toBe(80))
  it('applies SAVE50', () => expect(calculateDiscount(100, 'SAVE50')).toBe(50))
  it('invalid coupon', () => expect(calculateDiscount(100, 'INVALID')).toBe(100))
  it('no coupon', () => expect(calculateDiscount(100)).toBe(100))
})

Test Structure (AAA Pattern)

test('user registration flow', async () => {
  // Arrange
  const userData = { email: '[email protected]', password: 'secure123' }
  const mockEmailService = vi.fn()

  // Act
  const user = await registerUser(userData, mockEmailService)

  // Assert
  expect(user).toMatchObject({ email: '[email protected]', emailVerified: false })
  expect(mockEmailService).toHaveBeenCalledWith('[email protected]', expect.any(String))
})

Agentic Optimizations

ContextCommand
Coverage check (TS)vitest --coverage --reporter=dot
Coverage check (Python)uv run pytest --cov --cov-fail-under=80 -q
Find slow tests (TS)vitest --reporter=verbose
Find slow tests (Python)uv run pytest --durations=10 -q
Missing lines (Python)uv run pytest --cov --cov-report=term-missing

For detailed examples, advanced patterns, and best practices, see REFERENCE.md.

See Also

  • vitest-testing - TypeScript/JavaScript testing
  • python-testing - Python pytest testing
  • playwright-testing - E2E testing
  • mutation-testing - Validate test effectiveness

References

Comments

Markdown supported