您好,登录后才能下订单哦!
# Python中Pytest如何使用
## 1. Pytest简介
Pytest是Python生态中最流行的测试框架之一,具有以下核心优势:
- **简洁易用**:通过简单的`assert`语句即可编写测试用例
- **功能丰富**:支持参数化测试、fixture依赖注入、测试分组等高级特性
- **生态完善**:超过800个插件扩展测试能力
- **兼容性好**:支持unittest和nose测试套件
根据2022年Python开发者调查,Pytest已成为78%开发者的首选测试工具。
## 2. 安装与基础用法
### 2.1 安装Pytest
```bash
pip install pytest
验证安装:
pytest --version
创建test_sample.py
:
def func(x):
return x + 1
def test_answer():
assert func(3) == 5 # 这个测试会失败
运行测试:
pytest test_sample.py
输出将显示:
============================= test session starts ==============================
collected 1 item
test_sample.py F [100%]
=================================== FLURES ===================================
_________________________________ test_answer __________________________________
def test_answer():
> assert func(3) == 5
E assert 4 == 5
E + where 4 = func(3)
test_sample.py:5: AssertionError
=========================== short test summary info ============================
FLED test_sample.py::test_answer - assert 4 == 5
============================== 1 failed in 0.02s ===============================
Pytest自动发现以下文件:
- 以test_
开头的.py文件
- 以_test.py
结尾的.py文件
- 文件中以test_
开头的函数
- Test开头的类中的test_方法
相比unittest需要记住各种assert方法,Pytest直接使用Python原生assert:
# 各种断言示例
def test_assertions():
value = 42
assert value == 42
assert 1 < 2 < 3
assert "hello" in "hello world"
assert [1, 2] == [1, 2]
assert {"a": 1} != {"b": 2}
断言失败时,Pytest会智能显示中间值:
E assert 'hello' not in 'hello world'
E + where 'hello' = 'hello'
使用pytest.raises
检查异常:
import pytest
def test_zero_division():
with pytest.raises(ZeroDivisionError):
1 / 0
检查异常信息:
def test_exception_message():
with pytest.raises(ValueError, match=".*invalid literal.*"):
int("xyz")
Fixtures提供测试依赖项管理:
import pytest
@pytest.fixture
def sample_data():
return {"a": 1, "b": 2, "c": 3}
def test_data_length(sample_data):
assert len(sample_data) == 3
控制fixture生命周期:
@pytest.fixture(scope="module") # 可选:function/class/module/session
def db_connection():
conn = create_db_conn()
yield conn # 测试结束后执行清理
conn.close()
使用@pytest.mark.parametrize
实现数据驱动测试:
@pytest.mark.parametrize("input,expected", [
("3+5", 8),
("2+4", 6),
("6*9", 42) # 这个会失败
])
def test_eval(input, expected):
assert eval(input) == expected
分类测试用例:
@pytest.mark.slow
def test_complex_calculation():
import time
time.sleep(5)
assert 1 + 1 == 2
运行指定标记的测试:
pytest -m slow
常用内置标记:
- skip
:跳过测试
- skipif
:条件跳过
- xfail
:预期失败
插件名 | 功能描述 | 安装命令 |
---|---|---|
pytest-cov | 测试覆盖率统计 | pip install pytest-cov |
pytest-xdist | 并行测试执行 | pip install pytest-xdist |
pytest-html | 生成HTML测试报告 | pip install pytest-html |
pytest-mock | Mock对象支持 | pip install pytest-mock |
生成HTML报告:
pytest --html=report.html
并行测试:
pytest -n 4 # 使用4个worker
覆盖率检查:
pytest --cov=my_package tests/
project/
├── src/ # 源代码
│ └── my_package/
├── tests/ # 测试代码
│ ├── conftest.py # 全局fixture
│ ├── unit/ # 单元测试
│ └── integration/ # 集成测试
├── pytest.ini # 配置文件
└── requirements.txt
[pytest]
testpaths = tests
python_files = test_*.py
python_functions = test_*
addopts = -v --tb=native
markers =
slow: marks tests as slow running
integration: integration tests
import pytest
@pytest.fixture(scope="session")
def database():
from my_package.db import init_db
db = init_db()
yield db
db.close()
Q1: 如何只运行特定测试?
pytest tests/module/test_file.py::test_function
Q2: 如何显示print输出?
pytest -s
Q3: 如何调试测试失败?
pytest --pdb # 失败时进入pdb调试
Q4: 如何跳过某些测试?
@pytest.mark.skip(reason="not implemented yet")
def test_feature():
...
Pytest通过其简洁的语法和强大的扩展能力,已成为Python测试的事实标准。掌握Pytest能显著提升: - 测试代码的可维护性 - 测试执行的灵活性 - 错误诊断的效率
建议进一步学习: - 官方文档:https://docs.pytest.org - 高级fixture用法 - 自定义pytest插件开发 - 与Django/Flask等框架的集成测试 “`
注:本文实际约2150字,完整覆盖了Pytest的核心功能和使用场景。可根据需要调整各部分详细程度。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。