一键导入
testing-strategies
Expert knowledge in testing methodologies, test patterns, and quality assurance. Use when writing tests or setting up testing infrastructure.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Expert knowledge in testing methodologies, test patterns, and quality assurance. Use when writing tests or setting up testing infrastructure.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Expert knowledge in API design, authentication, caching, and backend best practices. Use for backend development tasks.
Expert knowledge in error diagnosis, debugging strategies, and self-healing patterns. Use when tasks fail or errors occur.
Expert knowledge in React patterns, component design, state management, and frontend best practices. Use for frontend development tasks.
Expert knowledge in project planning, requirements gathering, user stories, and scope management. Use when planning new projects or features.
Expert knowledge in quality assurance gates, code quality standards, and automated checks. Use when enforcing quality standards.
| name | testing-strategies |
| description | Expert knowledge in testing methodologies, test patterns, and quality assurance. Use when writing tests or setting up testing infrastructure. |
| allowed-tools | Read, Write, Edit, Bash, Glob, Grep |
Comprehensive testing strategies and patterns for ensuring code quality.
/\
/E2E\ 5% - Critical user journeys
/------\
/ Integ \ 15% - Service boundaries
/----------\
/ Unit \ 80% - Component logic
/--------------\
describe('calculateTotal', () => {
it('should apply discount correctly', () => {
// Arrange
const items = [{ price: 100, quantity: 1 }];
const discount = 0.1;
// Act
const result = calculateTotal(items, discount);
// Assert
expect(result).toBe(90);
});
});
describe('UserService', () => {
let service: UserService;
let mockRepo: MockUserRepository;
beforeEach(() => {
// Fresh instances for each test
mockRepo = new MockUserRepository();
service = new UserService(mockRepo);
});
afterEach(() => {
vi.clearAllMocks();
});
});
describe('validateEmail', () => {
it.each([
['test@example.com', true],
['user.name@domain.co.uk', true],
['invalid', false],
['@nodomain.com', false],
['no@tld', false],
])('validates %s as %s', (email, expected) => {
expect(validateEmail(email)).toBe(expected);
});
});
describe('divide', () => {
it('should handle positive numbers', () => {
expect(divide(10, 2)).toBe(5);
});
it('should handle negative numbers', () => {
expect(divide(-10, 2)).toBe(-5);
});
it('should handle zero dividend', () => {
expect(divide(0, 5)).toBe(0);
});
it('should throw on division by zero', () => {
expect(() => divide(10, 0)).toThrow('Division by zero');
});
it('should handle floating point', () => {
expect(divide(1, 3)).toBeCloseTo(0.333, 2);
});
});
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
describe('LoginForm', () => {
const mockOnSubmit = vi.fn();
beforeEach(() => {
mockOnSubmit.mockClear();
});
it('submits with valid data', async () => {
const user = userEvent.setup();
render(<LoginForm onSubmit={mockOnSubmit} />);
await user.type(screen.getByLabelText(/email/i), 'test@example.com');
await user.type(screen.getByLabelText(/password/i), 'password123');
await user.click(screen.getByRole('button', { name: /submit/i }));
await waitFor(() => {
expect(mockOnSubmit).toHaveBeenCalledWith({
email: 'test@example.com',
password: 'password123',
});
});
});
it('shows validation errors', async () => {
const user = userEvent.setup();
render(<LoginForm onSubmit={mockOnSubmit} />);
await user.click(screen.getByRole('button', { name: /submit/i }));
expect(await screen.findByText(/email is required/i)).toBeInTheDocument();
expect(mockOnSubmit).not.toHaveBeenCalled();
});
});
import { renderHook, act, waitFor } from '@testing-library/react';
describe('useCounter', () => {
it('increments counter', () => {
const { result } = renderHook(() => useCounter(0));
act(() => {
result.current.increment();
});
expect(result.current.count).toBe(1);
});
});
describe('useAsync', () => {
it('handles async operation', async () => {
const mockFetch = vi.fn().mockResolvedValue({ data: 'test' });
const { result } = renderHook(() => useAsync(mockFetch));
expect(result.current.isLoading).toBe(true);
await waitFor(() => {
expect(result.current.isLoading).toBe(false);
});
expect(result.current.data).toEqual({ data: 'test' });
});
});
import { testClient } from 'hono/testing';
import app from '../src/index';
describe('Users API', () => {
const client = testClient(app);
beforeEach(async () => {
await db.delete(users);
});
it('creates and retrieves user', async () => {
// Create
const createRes = await client.api.v1.users.$post({
json: { name: 'Test', email: 'test@example.com', password: 'pass123' },
});
expect(createRes.status).toBe(201);
const created = await createRes.json();
// Retrieve
const getRes = await client.api.v1.users[':id'].$get({
param: { id: created.data.id },
});
expect(getRes.status).toBe(200);
const retrieved = await getRes.json();
expect(retrieved.data.email).toBe('test@example.com');
});
});
describe('UserRepository', () => {
const repo = new UserRepository();
beforeEach(async () => {
await db.delete(users);
});
it('creates and finds user', async () => {
const created = await repo.create({
name: 'Test User',
email: 'test@example.com',
});
const found = await repo.findById(created.id);
expect(found).toEqual(created);
});
it('returns null for non-existent user', async () => {
const found = await repo.findById('non-existent-id');
expect(found).toBeNull();
});
});
import { test, expect } from '@playwright/test';
test.describe('User Flow', () => {
test('complete registration and login flow', async ({ page }) => {
// Register
await page.goto('/register');
await page.fill('[name="email"]', 'new@example.com');
await page.fill('[name="password"]', 'Password123!');
await page.click('button[type="submit"]');
// Verify redirect to login
await expect(page).toHaveURL('/login');
// Login
await page.fill('[name="email"]', 'new@example.com');
await page.fill('[name="password"]', 'Password123!');
await page.click('button[type="submit"]');
// Verify dashboard access
await expect(page).toHaveURL('/dashboard');
await expect(page.locator('h1')).toContainText('Dashboard');
});
});
import { http, HttpResponse } from 'msw';
import { setupServer } from 'msw/node';
const handlers = [
http.get('/api/users', () => {
return HttpResponse.json({
success: true,
data: [{ id: '1', name: 'Test User' }],
});
}),
http.post('/api/users', async ({ request }) => {
const body = await request.json();
return HttpResponse.json(
{ success: true, data: { id: '2', ...body } },
{ status: 201 }
);
}),
];
export const server = setupServer(...handlers);
// Setup in test file
beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());
// Mock module
vi.mock('./api', () => ({
fetchUsers: vi.fn().mockResolvedValue([{ id: '1', name: 'Test' }]),
}));
// Mock implementation
const mockFetch = vi.fn();
mockFetch
.mockResolvedValueOnce({ data: 'first' })
.mockResolvedValueOnce({ data: 'second' });
// Spy on method
const spy = vi.spyOn(console, 'log');
expect(spy).toHaveBeenCalledWith('message');
| Metric | Minimum | Target |
|---|---|---|
| Statements | 70% | 85% |
| Branches | 65% | 80% |
| Functions | 70% | 85% |
| Lines | 70% | 85% |
tests/
├── unit/ # Unit tests
│ ├── utils/
│ └── services/
├── integration/ # Integration tests
│ ├── api/
│ └── db/
├── e2e/ # E2E tests
│ ├── auth.spec.ts
│ └── dashboard.spec.ts
├── fixtures/ # Test data
├── mocks/ # Mock implementations
└── setup.ts # Global setup