Agent skill
testing-unit
Unit testing patterns for isolated business logic tests — AAA pattern, parametrized tests (test.each, @pytest.mark.parametrize), fixture scoping (function/module/session), mocking with MSW/VCR at network level, and test data management with factories (FactoryBoy, faker-js). Use when writing unit tests, setting up mocks, structuring test data, optimizing test speed, choosing fixture scope, or reducing test boilerplate. Covers Vitest, Jest, pytest.
Install this agent skill to your Project
npx add-skill https://github.com/yonatangross/orchestkit/tree/main/src/skills/testing-unit
Metadata
Additional technical details for this skill
- category
- document-asset-creation
SKILL.md
Unit Testing Patterns
Focused patterns for writing isolated, fast, maintainable unit tests. Covers test structure (AAA), parametrization, fixture management, HTTP mocking (MSW/VCR), and test data generation with factories.
Each category has individual rule files in rules/ loaded on-demand, plus reference material, checklists, and scaffolding scripts.
Core Principles (ALWAYS apply)
- AAA structure: Every test MUST follow Arrange-Act-Assert. Use
// Arrange,// Act,// Assertcomments for clarity. - Parametrize, don't duplicate: Use
test.each(TypeScript) or@pytest.mark.parametrize(Python) when testing multiple inputs. Never copy-paste the same test body with different values. - Fixture scoping matters: Use
scope="function"(default) for mutable data. Usescope="module"orscope="session"ONLY for expensive read-only resources (DB engines, ML models). Mutable data with shared scope causes flaky tests. - Speed target: Each unit test should run under 100ms. If it's slower, you're likely hitting I/O — mock it.
- Mock at the network level: Use MSW (TypeScript) or VCR.py (Python) to intercept HTTP at the network layer. Never mock
fetch/axios/requestsdirectly.
Quick Reference
| Category | Rules | Impact | When to Use |
|---|---|---|---|
| Unit Test Structure | 3 | CRITICAL | Writing any unit test |
| HTTP Mocking | 2 | HIGH | Mocking API calls in frontend/backend tests |
| Test Data Management | 3 | MEDIUM | Setting up test data, factories, fixtures |
Total: 8 rules across 3 categories, 4 references, 3 checklists, 1 example set, 3 scripts
Unit Test Structure
Core patterns for structuring isolated unit tests with clear phases and efficient execution.
| Rule | File | Key Pattern |
|---|---|---|
| AAA Pattern | rules/unit-aaa-pattern.md |
Arrange-Act-Assert with isolation |
| Fixture Scoping | rules/unit-fixture-scoping.md |
function/module/session scope selection |
| Parametrized Tests | rules/unit-parametrized.md |
test.each / @pytest.mark.parametrize |
Reference: references/aaa-pattern.md — detailed AAA implementation with checklist
HTTP Mocking
Network-level request interception for deterministic tests without hitting real APIs.
| Rule | File | Key Pattern |
|---|---|---|
| MSW 2.x | rules/mocking-msw.md |
Network-level mocking for frontend (TypeScript) |
| VCR.py | rules/mocking-vcr.md |
Record/replay HTTP cassettes (Python) |
References:
references/msw-2x-api.md— full MSW 2.x API (handlers, GraphQL, WebSocket, passthrough)references/stateful-testing.md— Hypothesis RuleBasedStateMachine for stateful tests
Checklists:
checklists/msw-setup-checklist.md— MSW installation, handler setup, test writingchecklists/vcr-checklist.md— VCR configuration, sensitive data filtering, CI setup
Examples: examples/handler-patterns.md — CRUD, error simulation, auth flow, file upload handlers
Test Data Management
Factories, fixtures, and seeding patterns for isolated, realistic test data.
| Rule | File | Key Pattern |
|---|---|---|
| Data Factories | rules/data-factories.md |
FactoryBoy / @faker-js builders |
| Data Fixtures | rules/data-fixtures.md |
JSON fixtures with composition |
| Seeding & Cleanup | rules/data-seeding-cleanup.md |
Automated DB seeding and teardown |
Reference: references/factory-patterns.md — advanced factory patterns (Sequence, SubFactory, Traits)
Checklist: checklists/test-data-checklist.md — data generation, cleanup, isolation verification
Quick Start
TypeScript (Vitest + MSW)
import { describe, test, expect, beforeAll, afterEach, afterAll } from 'vitest';
import { http, HttpResponse } from 'msw';
import { setupServer } from 'msw/node';
import { calculateDiscount } from './pricing';
// 1. Pure unit test with AAA pattern
describe('calculateDiscount', () => {
test.each([
[100, 0],
[150, 15],
[200, 20],
])('for order $%i returns $%i discount', (total, expected) => {
// Arrange
const order = { total };
// Act
const discount = calculateDiscount(order);
// Assert
expect(discount).toBe(expected);
});
});
// 2. MSW mocked API test
const server = setupServer(
http.get('/api/users/:id', ({ params }) => {
return HttpResponse.json({ id: params.id, name: 'Test User' });
})
);
beforeAll(() => server.listen({ onUnhandledRequest: 'error' }));
afterEach(() => server.resetHandlers());
afterAll(() => server.close());
test('fetches user from API', async () => {
// Arrange — MSW handler set up above
// Act
const response = await fetch('/api/users/123');
const data = await response.json();
// Assert
expect(data.name).toBe('Test User');
});
Python (pytest + FactoryBoy)
import pytest
from factory import Factory, Faker, SubFactory
class UserFactory(Factory):
class Meta:
model = dict
email = Faker('email')
name = Faker('name')
class TestUserService:
@pytest.mark.parametrize("role,can_edit", [
("admin", True),
("viewer", False),
])
def test_edit_permission(self, role, can_edit):
# Arrange
user = UserFactory(role=role)
# Act
result = user_can_edit(user)
# Assert
assert result == can_edit
Vitest 4.1 Features
aroundEach / aroundAll (preferred for DB transactions)
Wraps each test in setup/teardown — cleaner than separate beforeEach/afterEach for transactions:
test.aroundEach(async (runTest, { db }) => {
await db.transaction(runTest) // auto-rollback on test end
})
test('insert user', async ({ db }) => {
await db.insert({ name: 'Alice' })
// transaction auto-rolls back — no cleanup needed
})
aroundAll wraps entire suites the same way.
mockThrow / mockThrowOnce
Replaces the verbose mockImplementation(() => { throw err }) pattern:
const fn = vi.fn()
fn.mockThrow(new Error('connection lost')) // always throws
fn.mockThrowOnce(new Error('timeout')) // throws once, then normal
vi.defineHelper (clean stack traces)
Custom assertion helpers that point errors to the call site, not the helper internals:
const assertPair = vi.defineHelper((a, b) => {
expect(a).toEqual(b) // error points to where assertPair() was CALLED
})
Test Tags
Filter tests by tags in CLI — useful for CI fast paths:
// vitest.config.ts
test: {
tags: {
unit: { timeout: 5000 },
flaky: { retry: 3 },
}
}
vitest --tags-filter="unit and !flaky"
vitest --tags-filter="(unit or integration) and !slow"
Agent Reporter
Minimal output (failures only) — use in AI agent / CI contexts:
AI_AGENT=copilot vitest # auto-detect agent mode
Key Decisions
| Decision | Recommendation |
|---|---|
| Test framework (TS) | Vitest 4.1+ (modern, fast, aroundEach, test tags) or Jest (mature ecosystem) |
| Test framework (Python) | pytest with plugins (parametrize, asyncio, cov) |
| HTTP mocking (TS) | MSW 2.x at network level, never mock fetch/axios directly |
| HTTP mocking (Python) | VCR.py with cassettes, filter sensitive data |
| Test data | Factories (FactoryBoy/faker-js) over hardcoded fixtures |
| Fixture scope | scope="function" for mutable (default). module/session ONLY for expensive immutable resources |
| Execution time | Under 100ms per unit test — if slower, mock external calls |
| Coverage target | 90%+ business logic, 100% critical paths |
Common Mistakes
- Testing implementation details instead of public behavior (brittle tests)
- Mocking fetch/axios directly instead of using MSW at network level (incomplete coverage)
- Shared mutable state between tests via module-scoped fixtures (flaky tests)
- Hard-coded test data with duplicate IDs (test conflicts in parallel runs)
- No cleanup after database seeding (state leaks between tests)
- Over-mocking — testing your mocks instead of your code (false confidence)
- Verbose throw mocking —
mockImplementation(() => { throw err })instead ofmockThrow(err)(Vitest 4.1+)
Scripts
| Script | File | Purpose |
|---|---|---|
| Create Test Case | scripts/create-test-case.md |
Scaffold test file with auto-detected framework |
| Create Test Fixture | scripts/create-test-fixture.md |
Scaffold pytest fixture with context detection |
| Create MSW Handler | scripts/create-msw-handler.md |
Scaffold MSW handler for an API endpoint |
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
expect
Diff-aware AI browser testing — analyzes git changes, generates targeted test plans, and executes them via agent-browser. Reads git diff to determine what changed, maps changes to affected pages via route map, generates a test plan scoped to the diff, and runs it with pass/fail reporting. Use when testing UI changes, verifying PRs before merge, running regression checks on changed components, or validating that recent code changes don't break the user-facing experience.
github-operations
GitHub CLI operations for issues, PRs, milestones, and Projects v2. Covers gh commands, REST API patterns, and automation scripts. Use when managing GitHub issues, PRs, milestones, or Projects with gh.
chain-patterns
Chain patterns for CC 2.1.71 pipelines — MCP detection, handoff files, checkpoint-resume, worktree agents, CronCreate monitoring. Use when building multi-phase pipeline skills. Loaded via skills: field by pipeline skills (fix-issue, implement, brainstorm, verify). Not user-invocable.
storybook-mcp-integration
Storybook MCP server integration for component-aware AI development. Covers 6 tools across 3 toolsets (dev, docs, testing): component discovery via list-all-documentation/get-documentation, story previews via preview-stories, and automated testing via run-story-tests. Use when generating components that should reuse existing Storybook components, running component tests via MCP, or previewing stories in chat.
component-search
Search 21st.dev component registry for production-ready React components. Finds components by natural language description, filters by framework and style system, returns ranked results with install instructions. Use when looking for UI components, finding alternatives to existing components, or sourcing design system building blocks.
ai-ui-generation
AI-assisted UI generation patterns for json-render, v0, Bolt, and Cursor workflows. Covers prompt engineering for component generation, review checklists for AI-generated code, design token injection, refactoring for design system conformance, and CI gates for quality assurance. Use when generating UI components with AI tools, rendering multi-surface MCP visual output, reviewing AI-generated code, or integrating AI output into design systems.
Didn't find tool you were looking for?