Helps write and maintain automated tests to ensure code quality and coverage.

Install

mkdir -p .claude/skills/testing-code && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/2845" && unzip -o skill.zip -d .claude/skills/testing-code && rm skill.zip

Installs to .claude/skills/testing-code

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Write automated tests for features, validate functionality against acceptance criteria, and ensure code coverage. Use when writing test code, verifying functionality, or adding test coverage to existing code.
208 chars✓ has a “when” trigger
Intermediate

Key capabilities

  • Map acceptance criteria to unit, integration, and E2E tests
  • Configure mocking patterns for external dependencies
  • Verify test suite coverage against project specifications
  • Identify necessary test data fixtures

How it works

It processes project specification documents to generate specific test code based on the project's established mocking and assertion frameworks.

Inputs & outputs

You give it
Feature requirement document and acceptance criteria
You get back
Automated test cases and verification scripts

When to use testing-code

  • Write unit tests for new features
  • Validate code against acceptance criteria
  • Increase test coverage for existing code

About this skill

Testing Code

Core Workflow

Test writing follows a systematic approach: determine scope, understand patterns, map to requirements, write tests, verify coverage.

1. Determine Test Scope

Read project documentation:

  • docs/user-stories/US-###-*.md for acceptance criteria to test
  • docs/feature-spec/F-##-*.md for technical requirements
  • docs/api-contracts.yaml for API specifications
  • Existing test files to understand patterns

Choose test types needed:

  • Unit tests: Individual functions, pure logic, utilities
  • Integration tests: Multiple components working together, API endpoints
  • Component tests: UI components, user interactions
  • E2E tests: Complete user flows, critical paths
  • Contract tests: API request/response validation
  • Performance tests: Load, stress, benchmark testing

2. Understand Existing Patterns

Investigate current test approach:

  • Test framework (Jest, Vitest, Pytest, etc.)
  • Mocking patterns and utilities
  • Test data fixtures and setup/teardown
  • Assertion styles

Use code-finder agents if unfamiliar with test structure.

3. Map Tests to Requirements

Convert 3-5 acceptance criteria to specific test cases across test types:

Example mapping:

## User Story: US-101 User Login

### Test Cases
1. **Unit: Authentication service**
   - validateCredentials() returns true for valid email/password
   - validateCredentials() returns false for invalid password
   - checkAccountStatus() detects locked accounts

2. **Integration: Login endpoint**
   - POST /api/login with valid creds returns 200 + token
   - POST /api/login with invalid creds returns 401 + error
   - POST /api/login with locked account returns 403

3. **Component: Login form**
   - Submitting form calls login API
   - Error message displays on 401 response
   - Success redirects to /dashboard

4. **E2E: Complete login flow**
   - User enters credentials → submits → sees dashboard
   - User enters wrong password → sees error → retries successfully

4. Write Tests

Unit Test Structure:

describe('AuthService', () => {
  describe('validateCredentials', () => {
    it('returns true for valid email and password', async () => {
      const result = await authService.validateCredentials(
        '[email protected]',
        'ValidPass123'
      );
      expect(result).toBe(true);
    });

    it('returns false for invalid password', async () => {
      const result = await authService.validateCredentials(
        '[email protected]',
        'WrongPassword'
      );
      expect(result).toBe(false);
    });
  });
});

Integration Test Structure:

describe('POST /api/auth/login', () => {
  beforeEach(async () => {
    await resetTestDatabase();
    await createTestUser({
      email: '[email protected]',
      password: 'Test123!'
    });
  });

  it('returns 200 and token for valid credentials', async () => {
    const response = await request(app)
      .post('/api/auth/login')
      .send({ email: '[email protected]', password: 'Test123!' });

    expect(response.status).toBe(200);
    expect(response.body).toHaveProperty('token');
    expect(response.body.token).toMatch(/^eyJ/); // JWT format
  });

  it('returns 401 for invalid password', async () => {
    const response = await request(app)
      .post('/api/auth/login')
      .send({ email: '[email protected]', password: 'WrongPassword' });

    expect(response.status).toBe(401);
    expect(response.body.error).toBe('Invalid credentials');
  });
});

Component Test Structure:

describe('LoginForm', () => {
  it('submits form with valid data', async () => {
    const mockLogin = jest.fn().mockResolvedValue({ success: true });
    render(<LoginForm onLogin={mockLogin} />);

    await userEvent.type(screen.getByLabelText(/email/i), '[email protected]');
    await userEvent.type(screen.getByLabelText(/password/i), 'Password123');
    await userEvent.click(screen.getByRole('button', { name: /log in/i }));

    expect(mockLogin).toHaveBeenCalledWith({
      email: '[email protected]',
      password: 'Password123'
    });
  });

  it('displays error message on API failure', async () => {
    const mockLogin = jest.fn().mockRejectedValue(new Error('Invalid credentials'));
    render(<LoginForm onLogin={mockLogin} />);

    await userEvent.type(screen.getByLabelText(/email/i), '[email protected]');
    await userEvent.type(screen.getByLabelText(/password/i), 'wrong');
    await userEvent.click(screen.getByRole('button', { name: /log in/i }));

    expect(await screen.findByText(/invalid credentials/i)).toBeInTheDocument();
  });
});

E2E Test Structure:

test('user can log in successfully', async ({ page }) => {
  await page.goto('/login');

  await page.fill('[name="email"]', '[email protected]');
  await page.fill('[name="password"]', 'Test123!');
  await page.click('button:has-text("Log In")');

  await page.waitForURL('/dashboard');
  expect(page.url()).toContain('/dashboard');
});

5. Edge Cases & Error Scenarios

Include boundary conditions and error paths:

describe('Edge cases', () => {
  it('handles empty email gracefully', async () => {
    await expect(
      authService.validateCredentials('', 'password')
    ).rejects.toThrow('Email is required');
  });

  it('handles extremely long password', async () => {
    const longPassword = 'a'.repeat(10000);
    await expect(
      authService.validateCredentials('[email protected]', longPassword)
    ).rejects.toThrow('Password too long');
  });

  it('handles network timeout', async () => {
    jest.spyOn(global, 'fetch').mockImplementation(
      () => new Promise((resolve) => setTimeout(resolve, 10000))
    );

    await expect(
      authService.login('[email protected]', 'pass')
    ).rejects.toThrow('Request timeout');
  });
});

Edge cases to always include:

  • Empty/null inputs
  • Minimum/maximum values
  • Invalid formats
  • Network failures
  • API errors (4xx, 5xx)
  • Timeout conditions
  • Concurrent operations

6. Test Data & Fixtures

Create reusable test fixtures:

// tests/fixtures/users.ts
export const validUser = {
  email: '[email protected]',
  password: 'Test123!',
  name: 'Test User'
};

export const invalidUsers = {
  noEmail: { password: 'Test123!' },
  noPassword: { email: '[email protected]' },
  invalidEmail: { email: 'not-an-email', password: 'Test123!' },
  weakPassword: { email: '[email protected]', password: '123' }
};

// Use in tests
import { validUser, invalidUsers } from './fixtures/users';

it('validates user data', () => {
  expect(validate(validUser)).toBe(true);
  expect(validate(invalidUsers.noEmail)).toBe(false);
});

7. Parallel Test Implementation

When tests are independent (different modules, different test types), spawn parallel agents:

Pattern 1: Layer-based

  • Agent 1: Unit tests for services/utilities
  • Agent 2: Integration tests for API endpoints
  • Agent 3: Component tests for UI
  • Agent 4: E2E tests for critical flows

Pattern 2: Feature-based

  • Agent 1: All tests for Feature A
  • Agent 2: All tests for Feature B
  • Agent 3: All tests for Feature C

Pattern 3: Type-based

  • Agent 1: All unit tests
  • Agent 2: All integration tests
  • Agent 3: All E2E tests

8. Run & Verify Tests

Execute test suite:

# Unit tests
npm test -- --coverage

# Integration tests
npm run test:integration

# E2E tests
npm run test:e2e

# All tests
npm run test:all

Verify coverage:

  • Aim for >80% code coverage
  • 100% coverage of critical paths
  • All acceptance criteria have tests
  • All error scenarios tested

Quality Checklist

Coverage:

  • All acceptance criteria from user stories tested
  • Happy path covered
  • Edge cases included
  • Error scenarios tested
  • Boundary conditions validated

Structure:

  • Tests follow existing patterns
  • Clear test descriptions
  • Proper setup/teardown
  • No flaky tests (consistent results)
  • Tests are isolated (no interdependencies)

Data:

  • Test fixtures reusable
  • Database properly seeded/reset
  • Mocks used appropriately
  • No hardcoded test data in production

Integration:

  • Tests run in CI/CD
  • Coverage thresholds enforced
  • Fast feedback (quick tests)
  • Clear failure messages

When not to use it

  • Writing application production code
  • Manual QA testing workflows

Prerequisites

Testing framework (Jest/Pytest/Vitest)

Limitations

  • Limited by the quality of the provided requirements documentation
  • Does not guarantee logical correctness of the underlying code

How it compares

It bridges the gap between requirements and implementation, ensuring that every acceptance criterion has a measurable, automated verification step.

Compared to similar skills

testing-code side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
testing-code (this skill)110moReviewIntermediate
python-testing-patterns772moReviewIntermediate
dependency-upgrade265moReviewIntermediate
test-cases577moNo flagsBeginner

Try saying

Example prompts that trigger this skill in your AI assistant.

More by CaptainCrouton89

View all by CaptainCrouton89

reviewing-code

CaptainCrouton89

Systematically evaluate code changes for security, correctness, performance, and spec alignment. Use when reviewing PRs, assessing code quality, or verifying implementation against requirements.

21105

railway-cli-management

CaptainCrouton89

Deploy, manage services, view logs, and configure Railway infrastructure. Use when deploying to Railway, managing environment variables, viewing deployment logs, scaling services, or managing volumes.

9139

writing-like-user

CaptainCrouton89

Emulate the user's personal writing voice and style patterns. Use when the user asks to write content in their voice, draft documents, compose messages, or requests "write this like me" or "in my style."

687

gathering-requirements

CaptainCrouton89

Systematically clarify user needs, preferences, and constraints before planning or implementation. Classifies work type, investigates existing systems, discovers edge cases and integration points, resolves assumptions, and creates detailed specifications. Use when building features, enhancements, or integrations where requirements need clarification.

31

auditing-security

CaptainCrouton89

Identify and remediate vulnerabilities through systematic code analysis. Use when performing security assessments, pre-deployment reviews, compliance validation (OWASP, PCI-DSS, GDPR), investigating known vulnerabilities, or post-incident analysis.

10

documenting-code

CaptainCrouton89

Maintain project documentation synchronized with code. Keep feature specs, API contracts, and README current with init-project standards. Use when updating docs after code changes, adding new features, or ensuring documentation completeness.

14

Search skills

Search the agent skills registry