Get the FREE Ultimate OpenClaw Setup Guide →

designing-tests

Scanned
npx machina-cli add skill CloudAI-X/claude-workflow-v2/designing-tests --openclaw
Files (1)
SKILL.md
5.8 KB

Designing Tests

When to Load

  • Trigger: Adding tests, test strategy planning, improving coverage, setting up testing infrastructure
  • Skip: Non-test code changes where testing is not part of the task

Test Implementation Workflow

Copy this checklist and track progress:

Test Implementation Progress:
- [ ] Step 1: Identify what to test
- [ ] Step 2: Select appropriate test type
- [ ] Step 3: Write tests following templates
- [ ] Step 4: Run tests and verify passing
- [ ] Step 5: Check coverage meets targets
- [ ] Step 6: Fix any failing tests

Testing Pyramid

Apply the testing pyramid for balanced coverage:

        /\
       /  \     E2E Tests (10%)
      /----\    - Critical user journeys
     /      \   - Slow but comprehensive
    /--------\  Integration Tests (20%)
   /          \ - Component interactions
  /------------\ - API contracts
 /              \ Unit Tests (70%)
/________________\ - Fast, isolated
                   - Business logic focus

Framework Selection

JavaScript/TypeScript

TypeRecommendedAlternative
UnitVitestJest
IntegrationVitest + MSWJest + SuperTest
E2EPlaywrightCypress
ComponentTesting LibraryEnzyme

Python

TypeRecommendedAlternative
Unitpytestunittest
Integrationpytest + httpxpytest + requests
E2EPlaywrightSelenium
APIpytest + FastAPI TestClient-

Go

TypeRecommended
Unittesting + testify
Integrationtesting + httptest
E2Etesting + chromedp

Test Structure Templates

Unit Test

describe("[Unit] ComponentName", () => {
  describe("methodName", () => {
    it("should [expected behavior] when [condition]", () => {
      // Arrange
      const input = createTestInput();

      // Act
      const result = methodName(input);

      // Assert
      expect(result).toEqual(expectedOutput);
    });

    it("should throw error when [invalid condition]", () => {
      expect(() => methodName(invalidInput)).toThrow(ExpectedError);
    });
  });
});

Integration Test

describe("[Integration] API /users", () => {
  beforeAll(async () => {
    await setupTestDatabase();
  });

  afterAll(async () => {
    await teardownTestDatabase();
  });

  it("should create user and return 201", async () => {
    const response = await request(app)
      .post("/users")
      .send({ name: "Test", email: "test@example.com" });

    expect(response.status).toBe(201);
    expect(response.body.id).toBeDefined();
  });
});

E2E Test

describe("[E2E] User Registration Flow", () => {
  it("should complete registration successfully", async ({ page }) => {
    await page.goto("/register");

    await page.fill('[data-testid="email"]', "new@example.com");
    await page.fill('[data-testid="password"]', "SecurePass123!");
    await page.click('[data-testid="submit"]');

    await expect(page.locator(".welcome-message")).toBeVisible();
    await expect(page).toHaveURL("/dashboard");
  });
});

Coverage Strategy

What to Cover

  • ✅ Business logic (100%)
  • ✅ Edge cases and error handling (90%+)
  • ✅ API contracts (100%)
  • ✅ Critical user paths (E2E)
  • ⚠️ UI components (snapshot + interaction)
  • ❌ Third-party library internals
  • ❌ Simple getters/setters

Coverage Thresholds

{
  "coverageThreshold": {
    "global": {
      "branches": 80,
      "functions": 80,
      "lines": 80,
      "statements": 80
    },
    "src/core/": {
      "branches": 95,
      "functions": 95
    }
  }
}

Test Data Management

Factories/Builders

// factories/user.js
export const userFactory = (overrides = {}) => ({
  id: faker.string.uuid(),
  name: faker.person.fullName(),
  email: faker.internet.email(),
  createdAt: new Date(),
  ...overrides,
});

// Usage
const admin = userFactory({ role: "admin" });

Fixtures

// fixtures/users.json
{
  "validUser": { "name": "Test", "email": "test@example.com" },
  "invalidUser": { "name": "", "email": "invalid" }
}

Mocking Strategy

When to Mock

  • ✅ External APIs and services
  • ✅ Database in unit tests
  • ✅ Time/Date for determinism
  • ✅ Random values
  • ❌ Internal modules (usually)
  • ❌ The code under test

Mock Examples

// API mocking with MSW
import { http, HttpResponse } from "msw";

export const handlers = [
  http.get("/api/users", () => {
    return HttpResponse.json([{ id: 1, name: "John" }]);
  }),
];

// Time mocking
vi.useFakeTimers();
vi.setSystemTime(new Date("2024-01-01"));

Test Validation Loop

After writing tests, run this validation:

Test Validation:
- [ ] All tests pass: `npm test`
- [ ] Coverage meets thresholds: `npm test -- --coverage`
- [ ] No flaky tests (run multiple times)
- [ ] Tests are independent (order doesn't matter)
- [ ] Test names clearly describe behavior

If any tests fail, fix them before proceeding. If coverage is below target, add more tests for uncovered code paths.

# Run tests
npm test

# Run with coverage
npm test -- --coverage

# Run specific test file
npm test -- path/to/test.spec.ts

# Run in watch mode during development
npm test -- --watch

Source

git clone https://github.com/CloudAI-X/claude-workflow-v2/blob/main/skills/designing-tests/SKILL.mdView on GitHub

Overview

This skill designs testing strategies for any codebase and guides you from planning to infrastructure. It covers selecting the right test types (unit, integration, E2E), applying the Testing Pyramid, and using framework templates to ensure reliable, maintainable tests.

How This Skill Works

Start with the Test Implementation Workflow to identify what to test, choose appropriate test types, and write tests using the provided templates. Apply the Testing Pyramid to balance coverage, then select language-specific frameworks. Use the Unit/Integration/E2E templates to keep tests consistent and maintainable.

When to Use It

  • Adding tests or planning a test strategy for a codebase
  • Improving coverage across modules and APIs
  • Setting up or evolving testing infrastructure
  • Debugging failing or flaky tests
  • When asked about unit, integration, or E2E testing approaches

Quick Start

  1. Step 1: Identify what to test and select the appropriate test types using the Test Implementation Progress
  2. Step 2: Write tests following the Unit/Integration/E2E templates
  3. Step 3: Run tests, verify passing, and check coverage against targets; fix any failures

Best Practices

  • Follow the Test Implementation Progress: identify what to test, select test types, write tests, run and verify coverage, fix failures
  • Apply the Testing Pyramid guidance: unit ~70%, integration ~20%, E2E ~10% for balanced coverage
  • Choose language-specific frameworks from the Framework Selection tables (JS/TS, Python, Go)
  • Reuse the provided Test Structure Templates for Unit, Integration, and E2E tests
  • Aim for high coverage on business logic and API contracts, while monitoring UI tests separately

Example Use Cases

  • In a JavaScript/TypeScript project, implement unit tests with Vitest and an integration suite with Vitest + MSW
  • Add an integration test for the /users API using Vitest + MSW or Jest + SuperTest
  • Create an E2E test flow for user signup using Playwright (or Cypress as an alternative)
  • In a Python microservice, set up pytest unit tests, pytest + httpx for integration tests, and Playwright for E2E
  • In a Go service, write unit tests with testing + testify and an integration suite with testing + httptest

Frequently Asked Questions

Add this skill to your agents
Sponsor this space

Reach thousands of developers