Python 单元测试进阶:pytest 参数化与 fixture
·
Python 单元测试进阶:pytest 参数化与 fixture
1. 参数化测试
参数化允许用不同数据运行同一测试逻辑,避免重复代码。使用 @pytest.mark.parametrize 装饰器实现:
import pytest
# 测试函数:平方计算
def square(x):
return x ** 2
# 参数化测试用例
@pytest.mark.parametrize("input_val, expected", [
(2, 4), # 输入2,预期4
(-3, 9), # 输入-3,预期9
(0, 0) # 输入0,预期0
])
def test_square(input_val, expected):
assert square(input_val) == expected
- 优势:覆盖多组数据只需一个测试函数。
- 语法:
@pytest.mark.parametrize("参数名", 数据列表),数据列表为元组列表。
2. Fixture 机制
Fixture 提供可复用的测试资源(如数据库连接、配置文件),通过 @pytest.fixture 定义:
import pytest
# 定义fixture:模拟数据库连接
@pytest.fixture
def db_connection():
conn = create_dummy_db() # 创建模拟数据库
yield conn # 返回资源
conn.close() # 测试后自动清理
# 使用fixture的测试
def test_db_query(db_connection):
result = db_connection.execute("SELECT * FROM users")
assert len(result) > 0
- 特点:
- 自动清理:
yield后的代码在测试结束后执行。 - 作用域控制:通过
scope参数(如scope="module")管理生命周期。
- 自动清理:
- 依赖注入:测试函数声明参数(如
db_connection)即可使用 fixture。
3. 参数化与 Fixture 结合
在 fixture 中生成动态数据,实现更灵活的测试:
import pytest
# Fixture生成动态数据
@pytest.fixture(params=["admin", "user", "guest"])
def user_role(request):
return request.param # 返回参数化数据
# 测试不同用户权限
def test_access_control(user_role):
if user_role == "admin":
assert has_admin_access() is True
else:
assert has_admin_access() is False
- 流程:
- Fixture 的
params定义多组数据。 request.param获取当前测试的数据值。- 测试函数通过参数接收数据。
- Fixture 的
4. 最佳实践
- 参数化:
- 边界值测试:如
(999, 1000)测试临界点。 - 错误数据测试:如
("abc", TypeError)。
- 边界值测试:如
- Fixture:
- 共享资源:用
scope="session"避免重复初始化。 - 模块化:将 fixture 放在
conftest.py中供多文件使用。
- 共享资源:用
示例场景:测试登录功能
- 参数化:不同用户名/密码组合
- Fixture:模拟登录会话
@pytest.mark.parametrize("username, password", [("user1", "pass1"), ("user2", "pass2")]) def test_login(login_session, username, password): response = login_session.post(username, password) assert response.status_code == 200
通过参数化和 fixture,可显著提升测试代码的简洁性和覆盖范围,同时确保资源高效管理。
更多推荐
所有评论(0)