3.6 KiB
3.6 KiB
测试指南
测试策略
测试金字塔
┌───────┐
│ E2E │ 少量端到端测试
┌┴───────┴┐
│ Integration│ API和组件集成测试
┌┴──────────┴┐
│ Unit │ 大量单元测试
┌┴────────────┴┐
测试覆盖目标
| 层级 | 覆盖率目标 |
|---|---|
| 单元测试 | 80%+ |
| 集成测试 | 60%+ |
| E2E测试 | 关键流程覆盖 |
后端测试
目录结构
tests/
├── conftest.py # pytest配置和fixture
├── unit/ # 单元测试
│ ├── services/
│ └── models/
├── integration/ # 集成测试
│ └── api/
└── fixtures/ # 测试数据
运行测试
# 运行所有测试
pytest
# 运行单元测试
pytest tests/unit/
# 运行集成测试
pytest tests/integration/
# 带覆盖率
pytest --cov=app --cov-report=html
编写单元测试
import pytest
from app.services.user_service import UserService
from app.models import User
@pytest.fixture
def user_service(db_session):
return UserService(session=db_session)
@pytest.fixture
def sample_user():
return User(
id=1,
email="test@example.com",
username="testuser"
)
def test_get_user_by_id(user_service, sample_user, db_session):
db_session.add(sample_user)
db_session.commit()
result = user_service.get_user_by_id(1)
assert result is not None
assert result.email == "test@example.com"
Fixtures
常用Fixtures(conftest.py):
@pytest.fixture
def db_session():
"""数据库会话"""
...
@pytest.fixture
def client():
"""测试客户端"""
...
@pytest.fixture
def auth_headers():
"""认证头"""
...
前端测试
工具链
- Vitest - 单元测试
- React Testing Library - 组件测试
- Playwright - E2E测试
运行测试
# 单元测试
npm run test
# E2E测试
npm run test:e2e
# 覆盖率
npm run test:coverage
组件测试示例
import { render, screen, userEvent } from '@testing-library/react';
import { Button } from './Button';
describe('Button', () => {
it('renders with label', () => {
render(<Button label="Click me" onClick={() => {}} />);
expect(screen.getByText('Click me')).toBeInTheDocument();
});
it('calls onClick when clicked', async () => {
const onClick = vi.fn();
render(<Button label="Click me" onClick={onClick} />);
await userEvent.click(screen.getByText('Click me'));
expect(onClick).toHaveBeenCalled();
});
});
E2E测试
使用Playwright进行端到端测试:
import { test, expect } from '@playwright/test';
test.describe('登录流程', () => {
test('应该能够登录并跳转到dashboard', async ({ page }) => {
await page.goto('/login');
await page.fill('[name="email"]', 'test@example.com');
await page.fill('[name="password"]', 'password123');
await page.click('[type="submit"]');
await expect(page).toHaveURL('/dashboard');
await expect(page.locator('h1')).toContainText('品牌健康中心');
});
});
CI集成
测试在每次PR时自动运行:
# .github/workflows/test.yml
name: Test
on: [pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run tests
run: |
docker-compose up -d
pytest
npm run test:e2e