### pytest parametrize 参数化用法详解
`pytest` 是 Python 中非常流行的单元测试框架,其 `parametrize` 功能可以方便地实现参数化测试。通过该功能,可以在单个测试函数中运行多组输入数据并验证预期结果。
#### 基本语法
`@pytest.mark.parametrize` 装饰器用于指定一组或多组参数及其对应的期望值。以下是基本的语法结构:
```python
import pytest
@pytest.mark.parametrize("input1, input2, expected", [
(case1_input1, case1_input2, case1_expected),
(case2_input1, case2_input2, case2_expected),
])
def test_function(input1, input2, expected):
result = some_function(input1, input2)
assert result == expected
```
上述代码表示对于每一对 `(input1, input2)` 和 `expected` 的组合,都会执行一次 `test_function` 测试函数[^2]。
---
#### 示例:加法运算的参数化测试
假设我们有一个简单的加法函数 `add(a, b)`,可以通过 `parametrize` 对不同输入进行测试:
```python
import pytest
def add(a, b):
return a + b
data = [(1, 2, 3), (-1, -1, -2), (0, 0, 0)]
@pytest.mark.parametrize("a,b,expected", data)
def test_add(a, b, expected):
result = add(a, b)
assert result == expected
```
在这个例子中,`data` 列表包含了三组测试数据,分别对应三种情况下的输入和期望输出。每次调用 `test_add` 函数时,都会传入一个新的参数组合。
---
#### 多重参数化
如果需要对多个参数进行独立的参数化,则可以叠加多个 `@pytest.mark.parametrize` 装饰器。此时,测试案例的数量将是各参数集合大小的 **笛卡尔积**。
```python
import pytest
data1 = [1, 2]
data2 = ["a", "b", "c"]
@pytest.mark.parametrize("num", data1)
@pytest.mark.parametrize("char", data2)
def test_cartesian_product(num, char):
print(f"\n测试数据:{num}-{char}")
```
在此示例中,`data1` 包含两个数值 `[1, 2]`,而 `data2` 包含三个字符 `["a", "b", "c"]`。因此总共会产生 \(2 \times 3 = 6\) 条测试用例[^4]。
---
#### 使用 fixtures 结合参数化
除了普通的变量外,还可以将 `fixtures` 与 `parametrize` 配合使用。这使得复杂场景中的依赖注入更加灵活。
```python
import pytest
@pytest.fixture(params=[1, 2, 3])
def fixture_data(request):
return request.param
@pytest.mark.parametrize("multiplier", [10, 100])
def test_fixture_with_param(fixture_data, multiplier):
result = fixture_data * multiplier
print(f"\nfixture 数据: {fixture_data}, 倍数: {multiplier} -> 结果: {result}")
```
此代码片段展示了如何结合 `request.param` 提供的数据以及外部参数化来构建更复杂的测试逻辑[^5]。
---
#### 注意事项
- 如果某些情况下不需要特定的参数组合,可通过条件跳过部分测试:
```python
import pytest
@pytest.mark.parametrize("value", [-1, 0, 1])
def test_positive(value):
if value < 0:
pytest.skip("负数不适用")
assert value >= 0
```
- 当涉及大量数据集时,建议将测试数据存储到外部文件(如 JSON 或 CSV),并通过读取方式加载至脚本中。
---