Skip to content

测试指南

一句话总结:保障代码质量,减少 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-mockMockpytest --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)— 端到端测试框架


十、下一步

完成本章后,进入:

OPC 超级个体实战指南