skills/testing/SKILL.md
Design and implement comprehensive test suites. Covers unit testing, integration testing, E2E testing with Playwright, API testing, mocking strategies, test data factories, TDD workflow, snapshot testing, coverage targets, and CI integration. Use when writing tests, designing test architecture, or debugging test failures.
npx skillsauth add RaheesAhmed/SajiCode testing-patternsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
/ E2E \ ← Few: critical user flows only
/----------\
/ Integration \ ← Medium: API routes, DB queries
/----------------\
/ Unit Tests \ ← Many: business logic, utils, transforms
src/
├── services/
│ ├── user-service.ts
│ └── user-service.test.ts ← Colocated unit tests
├── routes/
│ ├── auth.ts
│ └── auth.integration.test.ts ← Integration tests
└── __tests__/
└── e2e/
└── auth-flow.spec.ts ← E2E tests
function createUser(overrides: Partial<User> = {}): User {
return {
id: crypto.randomUUID(),
email: `user-${Date.now()}@test.com`,
name: "Test User",
role: "USER",
createdAt: new Date(),
updatedAt: new Date(),
...overrides,
};
}
function createPost(overrides: Partial<Post> = {}): Post {
return {
id: crypto.randomUUID(),
title: "Test Post",
content: "Test content for testing purposes.",
published: false,
authorId: crypto.randomUUID(),
createdAt: new Date(),
...overrides,
};
}
describe("UserService", () => {
describe("createUser", () => {
it("creates user with valid input", async () => {
const input = { email: "[email protected]", name: "Valid User" };
const user = await userService.create(input);
expect(user.id).toBeDefined();
expect(user.email).toBe("[email protected]");
});
it("throws on duplicate email", async () => {
await userService.create({ email: "[email protected]", name: "First" });
await expect(userService.create({ email: "[email protected]", name: "Second" }))
.rejects.toThrow("Email already exists");
});
it("trims and lowercases email", async () => {
const user = await userService.create({ email: " [email protected] ", name: "User" });
expect(user.email).toBe("[email protected]");
});
it("rejects empty name", async () => {
await expect(userService.create({ email: "[email protected]", name: "" }))
.rejects.toThrow();
});
});
});
// Mock external service
vi.mock("../lib/email", () => ({
sendEmail: vi.fn().mockResolvedValue({ success: true }),
}));
// Mock with implementation
const mockFetch = vi.fn().mockImplementation((url: string) => {
if (url.includes("/users/123")) {
return Promise.resolve({ ok: true, json: () => Promise.resolve({ id: "123", name: "Test" }) });
}
return Promise.resolve({ ok: false, status: 404 });
});
// Spy on method
const logSpy = vi.spyOn(logger, "error");
await processOrder(invalidOrder);
expect(logSpy).toHaveBeenCalledWith("Order processing failed", expect.any(Object));
import { describe, it, expect, beforeAll, afterAll } from "vitest";
import request from "supertest";
import { app } from "../app";
describe("POST /api/auth/register", () => {
it("returns 201 with valid registration", async () => {
const res = await request(app)
.post("/api/auth/register")
.send({ email: "[email protected]", password: "SecurePass123", name: "New User" })
.expect(201);
expect(res.body.data.user.email).toBe("[email protected]");
expect(res.body.data.token).toBeDefined();
expect(res.body.data.user.password).toBeUndefined(); // Never expose
});
it("returns 400 for weak password", async () => {
await request(app)
.post("/api/auth/register")
.send({ email: "[email protected]", password: "weak", name: "User" })
.expect(400);
});
it("returns 409 for duplicate email", async () => {
await request(app).post("/api/auth/register")
.send({ email: "[email protected]", password: "Pass123!", name: "User" });
await request(app).post("/api/auth/register")
.send({ email: "[email protected]", password: "Pass456!", name: "User2" })
.expect(409);
});
});
import { test, expect } from "@playwright/test";
test.describe("Authentication Flow", () => {
test("user can register, login, and access dashboard", async ({ page }) => {
await page.goto("/register");
await page.getByLabel("Email").fill("[email protected]");
await page.getByLabel("Password").fill("SecurePass123!");
await page.getByLabel("Name").fill("E2E User");
await page.getByRole("button", { name: "Register" }).click();
await expect(page).toHaveURL("/dashboard");
await expect(page.getByText("Welcome, E2E User")).toBeVisible();
});
test("shows error on invalid credentials", async ({ page }) => {
await page.goto("/login");
await page.getByLabel("Email").fill("[email protected]");
await page.getByLabel("Password").fill("wrongpass");
await page.getByRole("button", { name: "Sign in" }).click();
await expect(page.getByText("Invalid credentials")).toBeVisible();
await expect(page).toHaveURL("/login");
});
});
| Layer | Target | Strategy | |-------|--------|----------| | Business logic | 90%+ | Unit tests | | API routes | 80%+ | Integration tests | | UI components | 70%+ | Component tests | | E2E flows | Critical paths | Playwright |
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- run: npm ci
- run: npm run test -- --coverage
- run: npx playwright install --with-deps
- run: npm run test:e2e
afterEach / afterAlldevelopment
Deep web research and data extraction skill. Systematically research ANY topic by fetching URLs, reading documentation, crawling API docs, evaluating npm/pypi packages, comparing technologies, and synthesizing findings into actionable recommendations. Use when researching libraries, frameworks, APIs, solutions, or any topic requiring web investigation.
development
Core engineering workflow that activates on EVERY task. Enforces systematic plan-before-code methodology, multi-file refactoring safety, dependency-aware changes, pre-flight verification, and zero-placeholder quality standards. Use PROACTIVELY on all coding tasks.
tools
Implement production styling systems with Tailwind CSS, vanilla CSS, or CSS-in-JS. Covers CSS architecture (BEM, utility-first, modules), design tokens, responsive patterns, animation systems, dark mode, container queries, print styles, and performance optimization. Use when implementing designs or building CSS architectures.
development
Build premium interfaces with shadcn/ui components, Radix primitives, and Tailwind CSS. Covers installation, component customization, theming, dark mode, form patterns with react-hook-form + Zod, data tables with sorting/filtering/pagination, command palette, toast patterns, and composable component architecture. Use when building UI with shadcn/ui.