testing
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseTesting Best Practices
测试最佳实践
Comprehensive testing strategies for modern JavaScript.
面向现代JavaScript的全面测试策略。
Instructions
说明
1. Test Structure (AAA Pattern)
1. 测试结构(AAA模式)
typescript
describe('UserService', () => {
it('should create a new user', async () => {
// Arrange
const userData = { name: 'John', email: 'john@example.com' };
// Act
const user = await userService.create(userData);
// Assert
expect(user.id).toBeDefined();
expect(user.name).toBe('John');
});
});typescript
describe('UserService', () => {
it('should create a new user', async () => {
// Arrange
const userData = { name: 'John', email: 'john@example.com' };
// Act
const user = await userService.create(userData);
// Assert
expect(user.id).toBeDefined();
expect(user.name).toBe('John');
});
});2. Component Testing (React Testing Library)
2. 组件测试(React Testing Library)
tsx
import { render, screen, fireEvent } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
describe('LoginForm', () => {
it('should submit form with credentials', async () => {
const onSubmit = vi.fn();
render(<LoginForm onSubmit={onSubmit} />);
await userEvent.type(screen.getByLabelText('Email'), 'test@example.com');
await userEvent.type(screen.getByLabelText('Password'), 'password123');
await userEvent.click(screen.getByRole('button', { name: /login/i }));
expect(onSubmit).toHaveBeenCalledWith({
email: 'test@example.com',
password: 'password123'
});
});
});tsx
import { render, screen, fireEvent } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
describe('LoginForm', () => {
it('should submit form with credentials', async () => {
const onSubmit = vi.fn();
render(<LoginForm onSubmit={onSubmit} />);
await userEvent.type(screen.getByLabelText('Email'), 'test@example.com');
await userEvent.type(screen.getByLabelText('Password'), 'password123');
await userEvent.click(screen.getByRole('button', { name: /login/i }));
expect(onSubmit).toHaveBeenCalledWith({
email: 'test@example.com',
password: 'password123'
});
});
});3. Mocking
3. Mocking
typescript
// Mock module
vi.mock('./api', () => ({
fetchUser: vi.fn().mockResolvedValue({ id: 1, name: 'John' })
}));
// Mock function
const mockFn = vi.fn();
mockFn.mockReturnValue('result');
mockFn.mockResolvedValue({ data: [] });
// Spy on method
const spy = vi.spyOn(console, 'log');typescript
// Mock module
vi.mock('./api', () => ({
fetchUser: vi.fn().mockResolvedValue({ id: 1, name: 'John' })
}));
// Mock function
const mockFn = vi.fn();
mockFn.mockReturnValue('result');
mockFn.mockResolvedValue({ data: [] });
// Spy on method
const spy = vi.spyOn(console, 'log');4. Async Testing
4. 异步测试
typescript
it('should fetch user data', async () => {
const user = await fetchUser(1);
expect(user).toEqual({
id: 1,
name: 'John'
});
});
it('should handle errors', async () => {
await expect(fetchUser(-1)).rejects.toThrow('User not found');
});typescript
it('should fetch user data', async () => {
const user = await fetchUser(1);
expect(user).toEqual({
id: 1,
name: 'John'
});
});
it('should handle errors', async () => {
await expect(fetchUser(-1)).rejects.toThrow('User not found');
});5. Test Coverage
5. 测试覆盖率
json
// vitest.config.ts
{
"test": {
"coverage": {
"provider": "v8",
"reporter": ["text", "html"],
"exclude": ["node_modules/", "test/"]
}
}
}json
// vitest.config.ts
{
"test": {
"coverage": {
"provider": "v8",
"reporter": ["text", "html"],
"exclude": ["node_modules/", "test/"]
}
}
}6. Testing Hooks
6. Hooks测试
typescript
import { renderHook, act } from '@testing-library/react';
describe('useCounter', () => {
it('should increment counter', () => {
const { result } = renderHook(() => useCounter());
act(() => {
result.current.increment();
});
expect(result.current.count).toBe(1);
});
});typescript
import { renderHook, act } from '@testing-library/react';
describe('useCounter', () => {
it('should increment counter', () => {
const { result } = renderHook(() => useCounter());
act(() => {
result.current.increment();
});
expect(result.current.count).toBe(1);
});
});7. Test Naming Conventions
7. 测试命名规范
typescript
// ✅ Good - descriptive
it('should return empty array when no users found')
it('should throw ValidationError when email is invalid')
// ❌ Bad - vague
it('works correctly')
it('handles error')typescript
// ✅ Good - descriptive
it('should return empty array when no users found')
it('should throw ValidationError when email is invalid')
// ❌ Bad - vague
it('works correctly')
it('handles error')