Pytest 核心特性与技术优势
核心特性详解
语法极简设计
测试用例仅需以 test_ 前缀命名函数或方法,无需继承任何基类。例如:
python
def test_addition():
assert 1 + 1 == 2
智能用例发现
自动扫描项目目录下匹配 test_*.py 或 *_test.py 模式的文件,支持递归搜索子目录。可通过 pytest --collect-only 查看发现的用例列表。
原生断言系统
直接使用 Python 内置关键字进行验证:
python
def test_list_operations():
items = ['a', 'b']
assert 'a' in items
assert items.pop() == 'b'
assert items is not None
高级功能实现
参数化测试示例
使用装饰器批量输入测试数据:
python
import pytest
@pytest.mark.parametrize("input,expected", [(1, 2), (3, 4)])
def test_increment(input, expected):
assert input + 1 == expected
Fixture 应用场景
创建可复用的测试资源:
python
import pytest
@pytest.fixture
def database():
conn = create_test_connection()
yield conn # 测试执行阶段
conn.close() # 清理阶段
def test_query(database):
result = database.execute("SELECT 1")
assert result == 1
生态系统扩展
常用插件推荐
pytest-xdist:并行测试加速pytest-mock:集成 unittest.mockpytest-asyncio:异步代码测试pytest-django:Django 项目专用
报告生成示例
安装 pytest-html 后执行:
bash
pytest --html=report.html
与传统框架对比
对比 unittest 的测试类写法:
python
# pytest 风格
def test_divide():
assert 6 / 2 == 3
# unittest 风格
import unittest
class TestMath(unittest.TestCase):
def test_divide(self):
self.assertEqual(6 / 2, 3)
性能优化技巧
- 使用
pytest --lf仅运行上次失败的用例 - 通过
-k参数按名称筛选用例 - 标记慢速测试:
@pytest.mark.slow配合-m "not slow"过滤
Pytest 快速入门:环境搭建与基础使用
环境搭建
python
pip install pytest==7.4.3 # 安装稳定版本
pytest --version # 验证安装
基础用例编写
创建 test_calculator.py:
python
def add(a, b):
return a + b
def test_add_positive():
assert add(2, 3) == 5 # 使用原生断言
运行测试用例
bash
pytest # 运行所有用例
pytest test_calculator.py # 运行指定文件
pytest -k "add" -v # 按名称过滤用例
Pytest 核心功能:Fixture 与参数化
Fixture 机制
定义测试前置/后置操作,支持作用域控制(如 function、module):
python
@pytest.fixture(scope="module")
def init_db():
db_conn = "模拟数据库连接"
yield db_conn
print("关闭连接")
def test_query(init_db):
assert init_db == "模拟数据库连接"
参数化测试
批量测试多组输入数据:
python
@pytest.mark.parametrize("input_num, expected", [(2, True), (3, False)])
def test_is_even(input_num, expected):
assert (input_num % 2 == 0) == expected
Pytest 企业级应用场景
接口自动化测试
结合 requests 和 Fixture 实现 Token 复用:
python
@pytest.fixture(scope="session")
def login_token():
response = requests.post("https://api.example.com/login", json={"user": "test"})
return response.json()["token"]
def test_get_user(login_token):
headers = {"Authorization": login_token}
response = requests.get("https://api.example.com/user/1", headers=headers)
assert response.status_code == 200
集成 CI/CD
在 Jenkinsfile 或 .gitlab-ci.yml 中配置自动化测试:
yaml
test:
script:
- pip install pytest
- pytest --html=report.html
最佳实践与优化建议
目录结构规范
project/
├── tests/
│ ├── unit/ # 单元测试
│ ├── api/ # 接口测试
│ └── conftest.py # 全局 Fixture
└── src/ # 业务代码
性能优化
- 使用
scope="session"减少重复初始化(如数据库连接)。 - 并行执行:通过
pytest-xdist插件加速测试(pytest -n 4)。
报告生成
bash
pytest --html=report.html --cov=src --cov-report=xml
通过上述方法,可快速将 Pytest 集成到企业级测试流程中,覆盖单元测试、接口测试及持续集成场景。