Designing tests skill

Designs and implements testing strategies for any codebase.

by CloudAI-X·MIT license·★ 1,416 Stars on the repo·GitHub ↗

Use now

Files of Designing tests

CloudAI-X/main1 file shown
SKILL.md
Show the full text256 lines

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
Type Recommended Alternative
Unit Vitest Jest
Integration Vitest + MSW Jest + SuperTest
E2E Playwright Cypress
Component Testing Library Vitest Browser Mode
Python
Type Recommended Alternative
Unit pytest unittest
Integration pytest + httpx pytest + requests
E2E Playwright Selenium
API pytest + FastAPI TestClient -
Go
Type Recommended
Unit testing + testify
Integration testing + httptest
E2E testing + 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: "[email protected]" });

    expect(response.status).toBe(201);
    expect(response.body.id).toBeDefined();
  });
});
E2E Test
import { test, expect } from "@playwright/test";

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

    await page.getByTestId("email").fill("[email protected]");
    await page.getByTestId("password").fill("SecurePass123!");
    await page.getByTestId("submit").click();

    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

Jest config shown; the Vitest equivalent is test.coverage.thresholds in vitest.config.

{
  "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": "[email protected]" },
  "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
1---
2name: designing-tests
3description: Designs and implements testing strategies for any codebase. Use when adding tests, improving coverage, setting up testing infrastructure, debugging test failures, or when asked about unit tests, integration tests, or E2E testing.
4---
5 
6# Designing Tests
7 
8### When to Load
9 
10- **Trigger**: Adding tests, test strategy planning, improving coverage, setting up testing infrastructure
11- **Skip**: Non-test code changes where testing is not part of the task
12 
13## Test Implementation Workflow
14 
15Copy this checklist and track progress:
16 
17```
18Test Implementation Progress:
19- [ ] Step 1: Identify what to test
20- [ ] Step 2: Select appropriate test type
21- [ ] Step 3: Write tests following templates
22- [ ] Step 4: Run tests and verify passing
23- [ ] Step 5: Check coverage meets targets
24- [ ] Step 6: Fix any failing tests
25```
26 
27## Testing Pyramid
28 
29Apply the testing pyramid for balanced coverage:
30 
31```
32 /\
33 / \ E2E Tests (10%)
34 /----\ - Critical user journeys
35 / \ - Slow but comprehensive
36 /--------\ Integration Tests (20%)
37 / \ - Component interactions
38 /------------\ - API contracts
39 / \ Unit Tests (70%)
40/________________\ - Fast, isolated
41 - Business logic focus
42```
43 
44## Framework Selection
45 
46### JavaScript/TypeScript
47 
48| Type | Recommended | Alternative |
49| ----------- | --------------- | ------------------- |
50| Unit | Vitest | Jest |
51| Integration | Vitest + MSW | Jest + SuperTest |
52| E2E | Playwright | Cypress |
53| Component | Testing Library | Vitest Browser Mode |
54 
55### Python
56 
57| Type | Recommended | Alternative |
58| ----------- | --------------------------- | ----------------- |
59| Unit | pytest | unittest |
60| Integration | pytest + httpx | pytest + requests |
61| E2E | Playwright | Selenium |
62| API | pytest + FastAPI TestClient | - |
63 
64### Go
65 
66| Type | Recommended |
67| ----------- | ------------------ |
68| Unit | testing + testify |
69| Integration | testing + httptest |
70| E2E | testing + chromedp |
71 
72## Test Structure Templates
73 
74### Unit Test
75 
76```javascript
77describe("[Unit] ComponentName", () => {
78 describe("methodName", () => {
79 it("should [expected behavior] when [condition]", () => {
80 // Arrange
81 const input = createTestInput();
82 
83 // Act
84 const result = methodName(input);
85 
86 // Assert
87 expect(result).toEqual(expectedOutput);
88 });
89 
90 it("should throw error when [invalid condition]", () => {
91 expect(() => methodName(invalidInput)).toThrow(ExpectedError);
92 });
93 });
94});
95```
96 
97### Integration Test
98 
99```javascript
100describe("[Integration] API /users", () => {
101 beforeAll(async () => {
102 await setupTestDatabase();
103 });
104 
105 afterAll(async () => {
106 await teardownTestDatabase();
107 });
108 
109 it("should create user and return 201", async () => {
110 const response = await request(app)
111 .post("/users")
112 .send({ name: "Test", email: "[email protected]" });
113 
114 expect(response.status).toBe(201);
115 expect(response.body.id).toBeDefined();
116 });
117});
118```
119 
120### E2E Test
121 
122```javascript
123import { test, expect } from "@playwright/test";
124 
125test.describe("[E2E] User Registration Flow", () => {
126 test("should complete registration successfully", async ({ page }) => {
127 await page.goto("/register");
128 
129 await page.getByTestId("email").fill("[email protected]");
130 await page.getByTestId("password").fill("SecurePass123!");
131 await page.getByTestId("submit").click();
132 
133 await expect(page.locator(".welcome-message")).toBeVisible();
134 await expect(page).toHaveURL("/dashboard");
135 });
136});
137```
138 
139## Coverage Strategy
140 
141### What to Cover
142 
143- ✅ Business logic (100%)
144- ✅ Edge cases and error handling (90%+)
145- ✅ API contracts (100%)
146- ✅ Critical user paths (E2E)
147- ⚠️ UI components (snapshot + interaction)
148- ❌ Third-party library internals
149- ❌ Simple getters/setters
150 
151### Coverage Thresholds
152 
153Jest config shown; the Vitest equivalent is `test.coverage.thresholds` in vitest.config.
154 
155```json
156{
157 "coverageThreshold": {
158 "global": {
159 "branches": 80,
160 "functions": 80,
161 "lines": 80,
162 "statements": 80
163 },
164 "src/core/": {
165 "branches": 95,
166 "functions": 95
167 }
168 }
169}
170```
171 
172## Test Data Management
173 
174### Factories/Builders
175 
176```javascript
177// factories/user.js
178export const userFactory = (overrides = {}) => ({
179 id: faker.string.uuid(),
180 name: faker.person.fullName(),
181 email: faker.internet.email(),
182 createdAt: new Date(),
183 ...overrides,
184});
185 
186// Usage
187const admin = userFactory({ role: "admin" });
188```
189 
190### Fixtures
191 
192```javascript
193// fixtures/users.json
194{
195 "validUser": { "name": "Test", "email": "[email protected]" },
196 "invalidUser": { "name": "", "email": "invalid" }
197}
198```
199 
200## Mocking Strategy
201 
202### When to Mock
203 
204- ✅ External APIs and services
205- ✅ Database in unit tests
206- ✅ Time/Date for determinism
207- ✅ Random values
208- ❌ Internal modules (usually)
209- ❌ The code under test
210 
211### Mock Examples
212 
213```javascript
214// API mocking with MSW
215import { http, HttpResponse } from "msw";
216 
217export const handlers = [
218 http.get("/api/users", () => {
219 return HttpResponse.json([{ id: 1, name: "John" }]);
220 }),
221];
222 
223// Time mocking
224vi.useFakeTimers();
225vi.setSystemTime(new Date("2024-01-01"));
226```
227 
228## Test Validation Loop
229 
230After writing tests, run this validation:
231 
232```
233Test Validation:
234- [ ] All tests pass: `npm test`
235- [ ] Coverage meets thresholds: `npm test -- --coverage`
236- [ ] No flaky tests (run multiple times)
237- [ ] Tests are independent (order doesn't matter)
238- [ ] Test names clearly describe behavior
239```
240 
241If any tests fail, fix them before proceeding. If coverage is below target, add more tests for uncovered code paths.
242 
243```bash
244# Run tests
245npm test
246 
247# Run with coverage
248npm test -- --coverage
249 
250# Run specific test file
251npm test -- path/to/test.spec.ts
252 
253# Run in watch mode during development
254npm test -- --watch
255```
256 

Discussion

Alternatives