All skills
jeffallan avatar

/test-master

@efebc44
by jeffallanjeffallan/claude-skills12k stars
1,124

Generates test files, creates mocking strategies, analyzes code coverage, designs test architectures, and produces test plans and defect reports across functional, performance, and security testing disciplines. Use when writing unit tests, integration tests, or E2E tests; creating test strategies or automation frameworks; analyzing coverage gaps; performance testing with k6 or Artillery; security testing with OWASP methods; debugging flaky tests; or working on QA, regression, test automation, quality gates, shift-left testing, or test maintenance.

Use this Skill: https://skilld.dev/gh/jeffallan/claude-skills/test-master

This session only. Nothing lands on disk.

referencestesting-anti-patterns.md

≈1.6k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Testing Anti-Patterns


Core Principle

"Test what the code does, not what the mocks do."

When tests verify mock behavior instead of actual functionality, they provide false confidence while catching zero real bugs.


The Five Anti-Patterns

Anti-Pattern 1: Testing Mock Behavior

The Problem: Verifying that mocks exist and were called, rather than testing actual component output.

// ❌ BAD: Testing the mock, not the behavior
it('should call the API', () => {
  const mockApi = jest.fn().mockResolvedValue({ data: 'test' });
  const service = new UserService(mockApi);

  service.getUser(1);

  expect(mockApi).toHaveBeenCalledWith(1); // Testing mock, not result
});
// ✅ GOOD: Testing actual behavior
it('should return user data from API', async () => {
  const mockApi = jest.fn().mockResolvedValue({ id: 1, name: 'Alice' });
  const service = new UserService(mockApi);

  const user = await service.getUser(1);

  expect(user.name).toBe('Alice'); // Testing actual output
});

Solution: Test the genuine component output. If you can only verify mock calls, reconsider whether the test adds value.


Anti-Pattern 2: Test-Only Methods in Production

The Problem: Adding methods to production classes solely for test setup or cleanup.

// ❌ BAD: Production code polluted with test concerns
class UserCache {
  private cache: Map<number, User> = new Map();

  getUser(id: number): User | undefined {
    return this.cache.get(id);
  }

  // This method exists ONLY for tests
  _resetForTesting(): void {
    this.cache.clear();
  }
}
// ✅ GOOD: Test utilities separate from production
// production/UserCache.ts
class UserCache {
  private cache: Map<number, User> = new Map();

  getUser(id: number): User | undefined {
    return this.cache.get(id);
  }
}

// test/helpers.ts
function createFreshCache(): UserCache {
  return new UserCache(); // Fresh instance per test
}

Solution: Relocate cleanup logic to test utility functions. Use fresh instances per test instead of reset methods.


Anti-Pattern 3: Mocking Without Understanding

The Problem: Over-mocking without grasping side effects, leading to tests that pass but hide real issues.

// ❌ BAD: Mocking everything without understanding
it('should process order', async () => {
  jest.mock('./inventory');
  jest.mock('./payment');
  jest.mock('./shipping');
  jest.mock('./notifications');

  const result = await processOrder(order);

  expect(result.success).toBe(true); // What did we actually test?
});
// ✅ GOOD: Strategic mocking with real components where possible
it('should process order with real inventory check', async () => {
  // Real inventory service against test database
  const inventory = new InventoryService(testDb);

  // Mock only external services
  const payment = mockPaymentGateway();

  const processor = new OrderProcessor(inventory, payment);
  const result = await processor.process(order);

  expect(result.success).toBe(true);
  expect(await inventory.getStock(order.itemId)).toBe(originalStock - 1);
});

Solution: Run tests with real implementations first to understand behavior. Then mock at the appropriate level - external services, not internal logic.


Anti-Pattern 4: Incomplete Mocks

The Problem: Partial mock responses missing downstream fields that production code expects.

// ❌ BAD: Incomplete mock response
const mockUserApi = jest.fn().mockResolvedValue({
  id: 1,
  name: 'Test User'
  // Missing: email, createdAt, permissions, settings...
});

// Test passes, but production crashes when accessing user.email
// ✅ GOOD: Complete mock matching real API response
const mockUserApi = jest.fn().mockResolvedValue({
  id: 1,
  name: 'Test User',
  email: 'test@example.com',
  createdAt: '2024-01-01T00:00:00Z',
  permissions: ['read', 'write'],
  settings: {
    theme: 'light',
    notifications: true
  }
});

// Or use a factory
const mockUserApi = jest.fn().mockResolvedValue(
  createMockUser({ name: 'Test User' }) // Factory fills defaults
);

Solution: Mirror complete real API response structure. Use factories to generate complete mock objects with sensible defaults.


Anti-Pattern 5: Integration Tests as Afterthought

The Problem: Treating testing as optional follow-up work rather than integral to development.

// ❌ BAD: "We'll add tests later"
// Day 1: Write 500 lines of code
// Day 2: Write 500 more lines
// Day 3: "We need to ship, tests can wait"
// Day 30: Catastrophic bug in production
// Day 31: "Why didn't we have tests?"
// ✅ GOOD: Tests are part of implementation
// Write failing test
it('should reject duplicate usernames', async () => {
  await createUser({ username: 'alice' });

  await expect(createUser({ username: 'alice' }))
    .rejects.toThrow('Username already exists');
});

// Make it pass
async function createUser(data: UserInput): Promise<User> {
  const existing = await db.users.findByUsername(data.username);
  if (existing) {
    throw new Error('Username already exists');
  }
  return db.users.create(data);
}

// Feature AND test ship together

Solution: Follow TDD - testing is implementation, not documentation. No feature is "done" without tests.


Detection Checklist

Review your tests for these warning signs:

Warning Sign Anti-Pattern
expect(mock).toHaveBeenCalled() without testing output Testing mock behavior
Methods starting with _ or ForTesting in production Test-only methods
Every dependency is mocked Mocking without understanding
Mocks return { success: true } only Incomplete mocks
Test files added weeks after feature ships Tests as afterthought

Quick Reference

Anti-Pattern Symptom Fix
Testing mocks Only mock assertions, no behavior tests Assert on actual output
Test-only methods _reset(), _setForTest() in prod Use fresh instances
Over-mocking 10+ mocks per test Test with real deps first
Incomplete mocks Minimal stub responses Use factories, match reality
Tests as afterthought Features ship untested TDD from the start

Content adapted from obra/superpowers by Jesse Vincent (@obra), MIT License.

Source: SKILL.md on GitHub

1 alert17d5 checks · Risk CRITICAL
  • Gen Agent Trust Hub17d

    The skill provides a comprehensive framework and reference guide for software testing, including unit, integration, and security testing. It involves processing user-provided code and API responses, which creates a surface for indirect prompt injection. Automated scanners flagged the documentation link and skill file, likely due to the inclusion of security testing payloads (e.g., SQL injection and XSS strings) used as diagnostic examples in the reference materials.

  • Socket17d

    No alerts

  • Snyk17d

    Risk: LOW · No issues

  • Runlayer6mo

    1/11 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at efebc44. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 months ago.

Steadyupdated 5 months ago
Other metadata
metadata
{
  "author": "https://github.com/Jeffallan",
  "version": "1.1.1",
  "domain": "quality",
  "triggers": "test, testing, QA, unit test, integration test, E2E, coverage, performance test, security test, regression, test strategy, test automation, test framework, quality metrics, defect, exploratory, usability, accessibility, localization, manual testing, shift-left, quality gate, flaky test, test maintenance",
  "role": "specialist",
  "scope": "testing",
  "output-format": "report",
  "related-skills": "fullstack-guardian, playwright-expert, devops-engineer, debugging-wizard, code-reviewer, feature-forge"
}
  • Testing
  • jest
  • vitest
  • pytest
  • test-automation
  • coverage
  • performance-testing
  • security-testing
  • e2e
  • quality-assurance

README badge

README badge for jeffallan/claude-skills/test-master

Generates test files, test strategies, and coverage analysis across unit, integration, E2E, performance, and security testing. Includes patterns for Jest, pytest, k6, and OWASP security testing, plus guidance on flaky test isolation, mock strategies, and test architecture design.

Generated from the current SKILL.md.

Does this skill cover performance and security testing, or just unit tests?
It covers functional, performance, and security testing. The skill includes reference guides for k6 and Artillery performance testing, OWASP security methods, and unit/integration/E2E test patterns.
What testing frameworks does this skill support?
It provides patterns for Jest, Vitest, pytest, and general E2E frameworks. The core workflow and assertions patterns are framework-agnostic; specific guidance is loaded from reference guides based on your tool choice.
Does this skill help debug flaky tests?
Yes. The core workflow includes a step to isolate flaky test failures by checking ordering dependencies, async handling, and adding stabilization logic or retries.
Can this skill generate test reports and defect documentation?
Yes. The skill outputs test plans with scope, test cases, coverage analysis, findings with severity ratings, and actionable fix recommendations.
Does this skill enforce mocking and isolation practices?
Yes. It requires mocking external dependencies, prohibits production data in tests, and forbids order-dependent tests. The skill enforces that each test runs independently.

Generated from the current SKILL.md. These answers refresh after source changes.