好的!下面给你详细介绍 Python 测试框架 pytest
,以及如何执行测试用例。
Python 单元测试框架之 pytest — 如何执行测试用例
一、pytest 简介
pytest
是 Python 中非常流行的测试框架,支持简单的测试用例编写,功能强大且扩展性好。- 支持断言重写、fixture 机制、参数化测试等。
二、安装 pytest
pip install pytest
三、编写测试用例示例
在项目目录中创建测试文件,文件名推荐以 test_
开头,函数名也以 test_
开头。
# test_sample.py
def func(x):
return x + 1
def test_func():
assert func(3) == 4
def test_func_fail():
assert func(3) == 5
四、执行测试用例
1. 在命令行直接执行
进入测试文件所在目录,运行:
pytest
- 会自动搜寻当前目录及子目录下所有
test_*.py
或*_test.py
文件,执行其中的测试函数。 - 默认输出详细的测试结果。
2. 指定某个测试文件执行
pytest test_sample.py
3. 指定某个测试函数执行
pytest test_sample.py::test_func
五、常用命令参数
参数 | 说明 |
---|---|
-v | 显示详细测试过程 |
-q | 简洁输出 |
-k "表达式" | 只执行匹配表达式的测试用例 |
--maxfail=N | 失败达到 N 个时停止测试 |
--tb=short/line/no | 调试信息显示简短、单行或不显示 |
-m "标记名" | 运行带有指定标记的测试(需使用 @pytest.mark ) |
六、示例:详细执行
pytest -v test_sample.py
输出类似:
test_sample.py::test_func PASSED
test_sample.py::test_func_fail FAILED
七、集成其他功能
- 参数化测试:
import pytest
@pytest.mark.parametrize("input,expected", [(1,2), (3,4), (5,6)])
def test_param(input, expected):
assert input + 1 == expected
- 使用 Fixture:
import pytest
@pytest.fixture
def resource():
print("Setup resource")
yield "resource"
print("Teardown resource")
def test_with_resource(resource):
assert resource == "resource"
好的!下面给你详细介绍 pytest 的高级用法,包括自定义插件、钩子函数,以及如何进行异常测试和跳过测试,最后也会简单说明如何和持续集成(CI)结合。
pytest 高级用法详解
一、自定义插件和钩子函数
1. 钩子函数 (Hook Functions)
pytest 支持钩子机制,可以在测试运行的不同阶段插入自定义逻辑。
例如,打印测试开始和结束提示:
# conftest.py(项目根目录或测试目录)
def pytest_runtest_setup(item):
print(f"\n开始执行测试: {item.name}")
def pytest_runtest_teardown(item, nextitem):
print(f"测试结束: {item.name}")
常用钩子函数:
pytest_sessionstart(session)
:测试会话开始pytest_sessionfinish(session, exitstatus)
:测试会话结束pytest_runtest_setup(item)
:单个测试用例执行前pytest_runtest_teardown(item, nextitem)
:单个测试用例执行后
2. 自定义命令行参数
可以通过插件或 conftest.py
自定义命令行参数:
# conftest.py
def pytest_addoption(parser):
parser.addoption(
"--env", action="store", default="dev", help="测试环境选择"
)
@pytest.fixture
def env(request):
return request.config.getoption("--env")
测试用例中:
def test_env(env):
print(f"当前测试环境: {env}")
运行:
pytest --env=prod
二、异常测试(验证是否抛出预期异常)
pytest 通过 pytest.raises()
上下文管理器验证异常:
import pytest
def func(x):
if x == 0:
raise ValueError("x 不能为0")
return 10 / x
def test_func_exception():
with pytest.raises(ValueError) as excinfo:
func(0)
assert "不能为0" in str(excinfo.value)
三、跳过测试和条件跳过
1. 跳过测试
使用装饰器:
import pytest
@pytest.mark.skip(reason="该功能尚未实现")
def test_not_implemented():
pass
2. 条件跳过
import sys
@pytest.mark.skipif(sys.platform == "win32", reason="Windows 不支持")
def test_not_on_windows():
pass
四、参数化组合与间接参数化
参数化可以组合多组数据,间接参数化可用 fixture 处理复杂数据:
import pytest
@pytest.mark.parametrize("x,y", [(1,2), (3,4)])
@pytest.mark.parametrize("z", [10, 20])
def test_multi(x, y, z):
assert (x + y) * z > 0
五、pytest 与持续集成(CI)集成简述
- 常见 CI 工具:Jenkins、GitHub Actions、GitLab CI、Travis CI 等。
- 只需在 CI 脚本里运行:
pytest --junitxml=report.xml
- 生成的
report.xml
可被 CI 工具识别,显示测试报告。 - 可结合覆盖率工具
coverage.py
:
pytest --cov=your_package --cov-report=xml
- 报告数据用于质量分析和门禁控制。
好的!下面给你一个完整示例,演示如何开发一个简单的 pytest 插件,以及如何在 GitHub Actions 中集成 pytest 和 coverage 来实现自动测试和覆盖率报告。
一、简单 pytest 插件开发示例
1. 插件功能
示例插件功能:在每个测试用例开始和结束时打印日志。
2. 目录结构
my_pytest_plugin/
├── conftest.py
├── test_sample.py
├── setup.py
├── README.md
3. 插件代码示例
conftest.py
def pytest_runtest_setup(item):
print(f"\n[PLUGIN] 开始测试: {item.name}")
def pytest_runtest_teardown(item, nextitem):
print(f"[PLUGIN] 测试结束: {item.name}")
test_sample.py
def test_example():
assert 1 + 1 == 2
setup.py
from setuptools import setup
setup(
name='my_pytest_plugin',
version='0.1',
py_modules=['conftest'],
entry_points={
'pytest11': [
'myplugin = conftest',
],
},
)
4. 使用插件
- 本地测试:
pytest -v
- 输出会包含插件打印的开始和结束信息。
二、GitHub Actions 集成 pytest + coverage 示例
1. 在项目根目录创建 .github/workflows/python-test.yml
name: Python Tests
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [3.8, 3.9, 3.10]
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install pytest coverage
- name: Run tests with coverage
run: |
coverage run -m pytest
coverage xml
- name: Upload coverage report
uses: actions/upload-artifact@v3
with:
name: coverage-report
path: coverage.xml
2. 说明
coverage run -m pytest
运行测试并收集覆盖率。- 生成
coverage.xml
,上传为构建产物。 - 可结合 Codecov、Coveralls 等服务进一步分析。
三、总结
功能 | 说明 |
---|---|
pytest 插件开发 | 用钩子函数扩展测试运行逻辑 |
GitHub Actions 集成 | 自动测试 + 覆盖率报告生成 |
持续集成可自动触发 | 每次推送/PR 自动执行测试 |
发表回复