Skip to content

测试与质量保证

本章讲解Cython项目的测试和质量保证。高质量代码需要全面的测试覆盖和持续的性能监控。

学习路径:单元测试 → 性能测试 → 静态分析 → 文档

核心工具:

  • pytest:Cython单元测试
  • time/perf_counter:性能基准测试
  • mypy:类型检查
  • sphinx:API文档

功能说明:使用pytest测试Cython模块。

tests/test_core.pyx
import pytest
cimport mypackage.core as core
def test_sum():
"""测试基本求和功能"""
assert core.sum(10) == 45
def test_sum_large():
"""测试大数求和"""
assert core.sum(1000000) == 499999500000

运行测试:

Terminal window
pytest tests/ -v

功能说明:生成测试覆盖率报告。

Terminal window
# 运行测试并生成覆盖率
pytest tests/ --cov=mypackage --cov-report=html
# 生成HTML报告
# 打开htmlcov/index.html查看

功能说明:测试边界条件和极端输入。

def test_edge_cases():
"""边界测试"""
# 空输入
assert core.sum(0) == 0
# 单元素
assert core.sum(1) == 0
# 负数输入
assert core.sum(-5) == -10 # -5 + -4 + -3 + -2 + -1 = -15? 实际0+...+(-1)

输出示例:

>>> core.sum(0)
0
>>> core.sum(1)
0
>>> core.sum(-5)
0

功能说明:测量函数执行时间。

benchmarks/bench_sum.py
import time
def benchmark_sum(n, iterations=100):
from mypackage import sum_fast
start = time.perf_counter()
for _ in range(iterations):
sum_fast(n)
elapsed = time.perf_counter() - start
return elapsed / iterations
# 运行
for n in [100, 1000, 10000, 100000, 1000000]:
t = benchmark_sum(n)
print(f"n={n}: {t*1000:.3f}ms")

输出示例:

n=100: 0.012ms
n=1000: 0.108ms
n=10000: 1.056ms
n=100000: 10.432ms
n=1000000: 104.521ms

功能说明:对比Python和Cython版本性能。

def test_performance():
from mypackage import sum_fast
import time
n = 10000000
# Cython版本
start = time.perf_counter()
result_cy = sum_fast(n)
time_cy = time.perf_counter() - start
# Python版本
start = time.perf_counter()
result_py = sum_slow(n)
time_py = time.perf_counter() - start
assert result_cy == result_py
print(f"Speedup: {time_py/time_cy:.1f}x")

输出示例:

Speedup: 68.5x

功能说明:确保优化后结果不变。

def test_regression():
"""回归测试:优化前后结果必须一致"""
test_cases = [
(0, 0),
(1, 0),
(10, 45),
(100, 4950),
(1000, 499500),
]
for n, expected in test_cases:
assert sum_fast(n) == expected

功能说明:mypy检查类型错误。

Terminal window
# mypy类型检查
mypy mypackage/*.pyx --ignore-missing-imports

输出示例:

mypackage/core.pyx:10: error: Argument 1 to "sum_fast" has incompatible type "str"; expected "int"

功能说明:使用pyflakes/rruff检查代码规范。

Terminal window
# pyflakes检查
pip install pyflakes
pyflakes mypackage/
# ruff检查(更快)
pip install ruff
ruff check mypackage/

功能说明:radon分析圈复杂度。

Terminal window
# 安装radon
pip install radon
# 分析复杂度
radon cc mypackage/*.pyx -a
# 复杂度等级:A(简单) -> F(复杂)

功能说明:Google风格文档字符串。

cpdef double sum_squares(int n) except -1.0:
"""Calculate sum of squares from 0 to n-1.
Args:
n: Number of terms to sum
Returns:
Sum of squares 0^2 + 1^2 + ... + (n-1)^2
Raises:
ValueError: If n is negative
Example:
>>> sum_squares(5)
30
"""
if n < 0:
raise ValueError("n must be non-negative")
return n * (n - 1) * (2 * n - 1) // 6

功能说明:Sphinx自动生成API文档。

docs/conf.py
extensions = ["sphinx.ext.autodoc"]

类型工具目的
单元测试pytest功能验证
性能测试time/perf_counter回归检测
类型检查mypy错误预防
代码规范ruff代码质量
文档sphinx可维护性
  1. 测试覆盖率至少80%
  2. 每次PR必须通过测试
  3. 性能测试防止退化(>10%退化需审查)
  4. docstring描述参数、返回值、异常

  1. 为Cython模块编写pytest测试(覆盖率>80%)
  2. 实现基准测试,对比Python和Cython性能
  3. 配置mypy类型检查,修复类型错误
  4. 为关键函数编写docstring文档
  5. 设置GitHub Actions CI/CD自动测试
  6. 使用radon分析代码复杂度,优化高复杂度函数