测试指南
一句话总结:保障代码质量,减少 Bug。
📍 本章定位
- 服务方案:全部方案
- 学习方式:📖 选学
- 在流程中的作用:保障代码质量,减少 Bug
- 核心知识点:测试类型、测试工具、测试策略
- 预计时长:按需查阅
- 完成后能做什么:能够编写高质量的测试
一、测试总览
1.1 测试类型
1.2 测试策略
| 测试类型 | 覆盖率 | 执行频率 | 工具 |
|---|---|---|---|
| 单元测试 | > 80% | 每次提交 | pytest, jest |
| 集成测试 | > 60% | 每次部署 | pytest, jest |
| 端到端测试 | > 40% | 每次发布 | Cypress, Playwright |
| 性能测试 | 关键路径 | 每月 | JMeter, Locust |
二、单元测试
2.1 Python 单元测试
问题:代码质量差,Bug 多。
解决方案:编写单元测试。
测试示例:
python
# test_calculator.py
import pytest
from calculator import add, subtract, multiply, divide
def test_add():
assert add(2, 3) == 5
assert add(-1, 1) == 0
assert add(0, 0) == 0
def test_subtract():
assert subtract(5, 3) == 2
assert subtract(1, 1) == 0
assert subtract(0, 0) == 0
def test_multiply():
assert multiply(2, 3) == 6
assert multiply(-1, 1) == -1
assert multiply(0, 0) == 0
def test_divide():
assert divide(6, 3) == 2
assert divide(1, 1) == 1
with pytest.raises(ZeroDivisionError):
divide(1, 0)运行测试:
bash
# 运行所有测试
pytest
# 运行特定测试
pytest test_calculator.py
# 运行带覆盖率的测试
pytest --cov=calculator最佳实践:
- 测试命名清晰
- 测试独立
- 测试可重复
2.2 JavaScript 单元测试
问题:代码质量差,Bug 多。
解决方案:编写单元测试。
测试示例:
javascript
// calculator.test.js
const { add, subtract, multiply, divide } = require('./calculator');
test('add', () => {
expect(add(2, 3)).toBe(5);
expect(add(-1, 1)).toBe(0);
expect(add(0, 0)).toBe(0);
});
test('subtract', () => {
expect(subtract(5, 3)).toBe(2);
expect(subtract(1, 1)).toBe(0);
expect(subtract(0, 0)).toBe(0);
});
test('multiply', () => {
expect(multiply(2, 3)).toBe(6);
expect(multiply(-1, 1)).toBe(-1);
expect(multiply(0, 0)).toBe(0);
});
test('divide', () => {
expect(divide(6, 3)).toBe(2);
expect(divide(1, 1)).toBe(1);
expect(() => divide(1, 0)).toThrow(ZeroDivisionError);
});运行测试:
bash
# 运行所有测试
npm test
# 运行带覆盖率的测试
npm test -- --coverage最佳实践:
- 测试命名清晰
- 测试独立
- 测试可重复
三、集成测试
3.1 API 测试
问题:API 接口质量差。
解决方案:编写 API 测试。
测试示例:
python
# test_api.py
import requests
def test_get_users():
response = requests.get('http://localhost:8000/users')
assert response.status_code == 200
assert len(response.json()) > 0
def test_create_user():
data = {'name': 'John', 'email': 'john@example.com'}
response = requests.post('http://localhost:8000/users', json=data)
assert response.status_code == 201
assert response.json()['name'] == 'John'
def test_update_user():
data = {'name': 'Jane'}
response = requests.put('http://localhost:8000/users/1', json=data)
assert response.status_code == 200
assert response.json()['name'] == 'Jane'
def test_delete_user():
response = requests.delete('http://localhost:8000/users/1')
assert response.status_code == 204运行测试:
bash
# 运行所有测试
pytest test_api.py
# 运行带覆盖率的测试
pytest --cov=api test_api.py最佳实践:
- 测试所有 API 端点
- 测试正常和异常情况
- 测试边界条件
3.2 数据库测试
问题:数据库操作质量差。
解决方案:编写数据库测试。
测试示例:
python
# test_database.py
import pytest
from database import Database
@pytest.fixture
def db():
return Database(':memory:')
def test_create_table(db):
db.create_table('users', ['id', 'name', 'email'])
assert db.table_exists('users')
def test_insert_data(db):
db.create_table('users', ['id', 'name', 'email'])
db.insert('users', {'id': 1, 'name': 'John', 'email': 'john@example.com'})
assert db.count('users') == 1
def test_query_data(db):
db.create_table('users', ['id', 'name', 'email'])
db.insert('users', {'id': 1, 'name': 'John', 'email': 'john@example.com'})
result = db.query('users', {'id': 1})
assert result[0]['name'] == 'John'运行测试:
bash
# 运行所有测试
pytest test_database.py
# 运行带覆盖率的测试
pytest --cov=database test_database.py最佳实践:
- 使用内存数据库
- 测试所有 CRUD 操作
- 测试事务和回滚
四、端到端测试
4.1 浏览器测试
问题:用户流程质量差。
解决方案:编写端到端测试。
测试示例:
javascript
// test_e2e.js
const { test, expect } = require('@playwright/test');
test('user can login', async ({ page }) => {
await page.goto('http://localhost:3000/login');
await page.fill('#email', 'john@example.com');
await page.fill('#password', 'password123');
await page.click('#login-button');
await expect(page).toHaveURL('http://localhost:3000/dashboard');
});
test('user can create post', async ({ page }) => {
await page.goto('http://localhost:3000/posts/new');
await page.fill('#title', 'My Post');
await page.fill('#content', 'This is my post content.');
await page.click('#submit-button');
await expect(page.locator('.post-title')).toHaveText('My Post');
});运行测试:
bash
# 运行所有测试
npx playwright test
# 运行特定测试
npx playwright test test_e2e.js
# 运行带 UI 的测试
npx playwright test --ui最佳实践:
- 测试关键用户流程
- 测试正常和异常情况
- 测试不同浏览器
4.2 移动端测试
问题:移动端质量差。
解决方案:编写移动端测试。
测试示例:
javascript
// test_mobile.js
const { test, expect } = require('@playwright/test');
test('mobile user can login', async ({ page }) => {
await page.goto('http://localhost:3000/login');
await page.fill('#email', 'john@example.com');
await page.fill('#password', 'password123');
await page.click('#login-button');
await expect(page).toHaveURL('http://localhost:3000/dashboard');
});运行测试:
bash
# 运行所有测试
npx playwright test --project=mobile
# 运行特定测试
npx playwright test test_mobile.js --project=mobile最佳实践:
- 测试不同设备
- 测试不同分辨率
- 测试触摸操作
五、性能测试
5.1 负载测试
问题:不知道系统负载能力。
解决方案:进行负载测试。
测试示例:
python
# test_load.py
from locust import HttpUser, task, between
class WebsiteUser(HttpUser):
wait_time = between(1, 3)
@task
def index(self):
self.client.get('/')
@task
def login(self):
self.client.post('/login', json={
'email': 'john@example.com',
'password': 'password123'
})运行测试:
bash
# 运行负载测试
locust -f test_load.py --host=http://localhost:8000
# 访问 http://localhost:8089 查看结果最佳实践:
- 模拟真实用户行为
- 逐步增加负载
- 监控系统资源
5.2 压力测试
问题:不知道系统极限。
解决方案:进行压力测试。
测试示例:
python
# test_stress.py
from locust import HttpUser, task, between
class WebsiteUser(HttpUser):
wait_time = between(0.1, 0.5)
@task
def index(self):
self.client.get('/')运行测试:
bash
# 运行压力测试
locust -f test_stress.py --host=http://localhost:8000 --users=1000 --spawn-rate=100
# 访问 http://localhost:8089 查看结果最佳实践:
- 逐步增加负载
- 监控系统资源
- 记录崩溃点
5.3 稳定性测试
问题:不知道系统稳定性。
解决方案:进行稳定性测试。
测试示例:
python
# test_stability.py
from locust import HttpUser, task, between
class WebsiteUser(HttpUser):
wait_time = between(1, 3)
@task
def index(self):
self.client.get('/')运行测试:
bash
# 运行稳定性测试
locust -f test_stability.py --host=http://localhost:8000 --users=100 --run-time=24h
# 访问 http://localhost:8089 查看结果最佳实践:
- 长时间运行
- 监控系统资源
- 记录异常
六、测试工具
6.1 Python 测试工具
| 工具 | 用途 | 命令 |
|---|---|---|
| pytest | 单元测试 | pytest |
| coverage | 覆盖率 | pytest --cov |
| pytest-xdist | 并行测试 | pytest -n auto |
| pytest-mock | Mock | pytest --mock |
6.2 JavaScript 测试工具
| 工具 | 用途 | 命令 |
|---|---|---|
| jest | 单元测试 | npm test |
| coverage | 覆盖率 | npm test -- --coverage |
| playwright | 端到端测试 | npx playwright test |
| cypress | 端到端测试 | npx cypress run |
6.3 性能测试工具
| 工具 | 用途 | 命令 |
|---|---|---|
| locust | 负载测试 | locust -f test.py |
| jmeter | 负载测试 | jmeter -n -t test.jmx |
| k6 | 负载测试 | k6 run test.js |
七、最佳实践
7.1 测试金字塔
问题:测试策略不合理。
解决方案:遵循测试金字塔。
金字塔结构:
比例建议:
- 单元测试:70%
- 集成测试:20%
- 端到端测试:10%
7.2 测试驱动开发
问题:代码质量差。
解决方案:使用测试驱动开发。
流程:
优点:
- 代码质量高
- Bug 少
- 易于维护
7.3 持续集成
问题:测试不及时。
解决方案:使用持续集成。
流程:
工具:
- GitHub Actions
- GitLab CI/CD
- Jenkins
八、核心洞察
核心洞察
测试是代码质量的保障。
- 单元测试:测试单个函数或类
- 集成测试:测试多个模块的交互
- 端到端测试:测试完整的用户流程
- 性能测试:测试系统的负载能力
记住:没有测试的代码是不可靠的。
九、参考与延伸
[1] pytest 官方文档(2026)— Python 测试框架
[2] jest 官方文档(2026)— JavaScript 测试框架
[3] playwright 官方文档(2026)— 端到端测试框架
十、下一步
完成本章后,进入: