Agent skill

Testing Code

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.

Stars 152
Forks 20

Install this agent skill to your Project

npx add-skill https://github.com/Microck/ordinary-claude-skills/tree/main/skills_all/testing-code

SKILL.md

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:

markdown
## 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:

javascript
describe('AuthService', () => {
  describe('validateCredentials', () => {
    it('returns true for valid email and password', async () => {
      const result = await authService.validateCredentials(
        'user@example.com',
        'ValidPass123'
      );
      expect(result).toBe(true);
    });

    it('returns false for invalid password', async () => {
      const result = await authService.validateCredentials(
        'user@example.com',
        'WrongPassword'
      );
      expect(result).toBe(false);
    });
  });
});

Integration Test Structure:

javascript
describe('POST /api/auth/login', () => {
  beforeEach(async () => {
    await resetTestDatabase();
    await createTestUser({
      email: 'test@example.com',
      password: 'Test123!'
    });
  });

  it('returns 200 and token for valid credentials', async () => {
    const response = await request(app)
      .post('/api/auth/login')
      .send({ email: 'test@example.com', 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: 'test@example.com', password: 'WrongPassword' });

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

Component Test Structure:

javascript
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), 'user@example.com');
    await userEvent.type(screen.getByLabelText(/password/i), 'Password123');
    await userEvent.click(screen.getByRole('button', { name: /log in/i }));

    expect(mockLogin).toHaveBeenCalledWith({
      email: 'user@example.com',
      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), 'user@example.com');
    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:

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

  await page.fill('[name="email"]', 'test@example.com');
  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:

javascript
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('user@example.com', 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('user@example.com', '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:

javascript
// tests/fixtures/users.ts
export const validUser = {
  email: 'test@example.com',
  password: 'Test123!',
  name: 'Test User'
};

export const invalidUsers = {
  noEmail: { password: 'Test123!' },
  noPassword: { email: 'test@example.com' },
  invalidEmail: { email: 'not-an-email', password: 'Test123!' },
  weakPassword: { email: 'test@example.com', 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:

bash
# 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

Expand your agent's capabilities with these related and highly-rated skills.

Microck/ordinary-claude-skills

nondominium-holochain-dna-dev

Specialized skill for nondominium Holochain DNA development, focusing on zome creation, entry patterns, integrity/coordinator architecture, ValueFlows compliance, and WASM optimization. Use when creating new zomes, implementing entry types, or modifying Holochain DNA code.

152 20
Explore
Microck/ordinary-claude-skills

fluidsim

Framework for computational fluid dynamics simulations using Python. Use when running fluid dynamics simulations including Navier-Stokes equations (2D/3D), shallow water equations, stratified flows, or when analyzing turbulence, vortex dynamics, or geophysical flows. Provides pseudospectral methods with FFT, HPC support, and comprehensive output analysis.

152 20
Explore
Microck/ordinary-claude-skills

metabolomics-workbench-database

Access NIH Metabolomics Workbench via REST API (4,200+ studies). Query metabolites, RefMet nomenclature, MS/NMR data, m/z searches, study metadata, for metabolomics and biomarker discovery.

152 20
Explore
Microck/ordinary-claude-skills

run-tests

Validate code changes by intelligently selecting and running the appropriate test suites. Use this when editing code to verify changes work correctly, run tests, validate functionality, or check for regressions. Automatically discovers affected test suites, selects the minimal set of venvs needed for validation, and handles test execution with Docker services as needed.

152 20
Explore
Microck/ordinary-claude-skills

skill-navigator

The 100th skill! Your intelligent guide to all 99 other skills. Recommends the perfect skill for any task, creates skill combinations, and helps you discover capabilities you didn't know you had.

152 20
Explore
Microck/ordinary-claude-skills

AgentDB Advanced Features

Master advanced AgentDB features including QUIC synchronization, multi-database management, custom distance metrics, hybrid search, and distributed systems integration. Use when building distributed AI systems, multi-agent coordination, or advanced vector search applications.

152 20
Explore

Didn't find tool you were looking for?

Be as detailed as possible for better results