--
:
--
:
--
第二阶段:fixture机制与参数化
最后更新于:
第二阶段:fixture机制与参数化
一、fixture机制
1.1 什么是fixture?
fixture是pytest最核心的特性,用于实现测试的前置条件准备和后置清理。它可以看作是测试用例的"依赖注入"系统。
1.2 基本用法
1import pytest
2
3@pytest.fixture
4def setup():
5 # 前置准备
6 print("\nSetup: 准备测试环境")
7 data = {"name": "test", "value": 42}
8 yield data # 返回数据给测试用例
9 # 后置清理
10 print("\nTeardown: 清理测试环境")
11
12def test_example(setup):
13 print(f"测试中使用fixture数据: {setup}")
14 assert setup["value"] == 421.3 fixture作用域
| 作用域 | 说明 | 使用场景 |
|---|---|---|
function | 每个测试函数执行一次(默认) | 每个测试需要独立的对象实例 |
class | 每个测试类执行一次 | 同一类的测试共享同一个资源 |
module | 每个测试模块执行一次 | 模块级别的共享资源 |
session | 整个测试会话执行一次 | 全局共享资源,如数据库连接 |
1.4 autouse自动执行
1@pytest.fixture(autouse=True)
2def auto_fixture():
3 print("\n[Auto] 自动执行的fixture")
4 yield
5 print("\n[Auto] 自动清理")1.5 fixture依赖
1@pytest.fixture
2def db_connection():
3 conn = create_connection()
4 yield conn
5 conn.close()
6
7@pytest.fixture
8def test_data(db_connection):
9 db_connection.insert(test_data)
10 yield test_data
11 db_connection.delete(test_data)二、参数化测试
2.1 基本用法
1import pytest
2
3@pytest.mark.parametrize("input,expected", [
4 (2, 4),
5 (3, 9),
6 (4, 16),
7])
8def test_square(input, expected):
9 assert input ** 2 == expected2.2 多参数参数化
1@pytest.mark.parametrize("a,b,expected", [
2 (2, 3, 5),
3 (0, 0, 0),
4 (-1, 1, 0),
5])
6def test_add(a, b, expected):
7 assert a + b == expected2.3 组合参数化
1@pytest.mark.parametrize("a", [1, 2, 3])
2@pytest.mark.parametrize("b", [4, 5])
3def test_combine(a, b):
4 # 测试组合: (1,4), (1,5), (2,4), (2,5), (3,4), (3,5)
5 assert a + b > 02.4 参数化ID
1@pytest.mark.parametrize("input,expected", [
2 (2, 4),
3 (3, 9),
4], ids=["two_squared", "three_squared"])
5def test_square(input, expected):
6 assert input ** 2 == expected三、断言系统
3.1 基本断言
1assert a == b # 相等断言
2assert a != b # 不相等断言
3assert a in b # 包含断言
4assert a is None # None断言
5assert isinstance(a, int) # 类型断言3.2 带消息的断言
1assert result == expected, f"期望{expected},实际{result}"3.3 异常断言
1# 断言抛出异常
2with pytest.raises(ValueError):
3 risky_operation()
4
5# 断言异常消息
6with pytest.raises(ValueError, match="divide by zero"):
7 divide(10, 0)
8
9# 获取异常信息
10with pytest.raises(ValueError) as exc_info:
11 divide(10, 0)
12assert "Cannot divide by zero" in str(exc_info.value)3.4 近似值断言
1# 使用pytest的approx
2from pytest import approx
3assert 0.1 + 0.2 == approx(0.3)
4assert 0.1 + 0.2 == approx(0.3, rel=1e-6)
5assert 0.1 + 0.2 == approx(0.3, abs=1e-9)四、示例代码
4.1 fixture示例
1# tests/test_fixture_demo.py
2import pytest
3from src.calculator import Calculator
4
5@pytest.fixture
6def calculator():
7 calc = Calculator()
8 return calc
9
10@pytest.fixture(scope="module")
11def module_data():
12 print("\n[Module Setup] 准备模块级数据")
13 data = {"start_value": 100}
14 yield data
15 print("\n[Module Teardown] 清理模块级数据")
16
17def test_add_with_fixture(calculator):
18 result = calculator.add(2, 3)
19 assert result == 54.2 参数化示例
1# tests/test_parametrize_demo.py
2import pytest
3from src.calculator import Calculator
4
5@pytest.fixture
6def calculator():
7 return Calculator()
8
9@pytest.mark.parametrize("a,b,expected", [
10 (2, 3, 5),
11 (0, 0, 0),
12 (-1, 1, 0),
13 (10, -5, 5),
14])
15def test_add_parametrize(calculator, a, b, expected):
16 result = calculator.add(a, b)
17 assert result == expected五、易错点与注意事项
5.1 fixture常见错误
- 作用域选择不当:需要共享资源时使用了
function作用域 - fixture命名冲突:不同层级的conftest.py中有同名fixture
- 忘记yield:fixture函数没有yield语句,导致测试无法获取数据
5.2 参数化常见错误
- 参数数量不匹配:parametrize装饰器的参数与测试函数参数数量不一致
- 数据格式错误:参数列表中的元组长度不一致
- 缺少import:忘记导入
pytest模块
5.3 断言常见错误
- 浮点数比较:直接比较浮点数可能导致精度问题,使用
approx - 异常断言位置:
pytest.raises()需要包裹会抛出异常的代码 - 断言消息过长:断言消息应简洁明了
六、小结
本阶段学习了pytest的核心功能,包括:
- fixture机制及作用域控制
- autouse自动执行
- 参数化测试
- 异常断言和近似值断言
📡
👤
作者:
阿海
🌐
版权:
本站文章除特别声明外,均采用
CC BY-NC-SA 4.0
协议,转载请注明来自
阿海 Blog!
- 01JMeter界面详解 2026-07-11
- 02性能测试学习路线 2026-07-11
- 03JMeter线程组配置详解 2026-07-11