在pytest框架中,可以使用多种方式进行参数化测试。以下是一些常见的参数化方式及其示例:
- 使用@pytest.mark.parametrize装饰器:可以使用pytest提供的@pytest.mark.parametrize装饰器来指定参数化测试的参数。下面是一个示例:
import pytest @pytest.mark.parametrize("num, expected", [ (1, 1), (2, 4), (3, 9) ]) def test_square(num, expected): assert num ** 2 == expected
在上面的示例中,通过给@pytest.mark.parametrize装饰器传递参数列表,每个参数列表都是一个参数化测试的参数组合。每个参数组合都会作为单独的测试用例执行。
- 使用pytest.fixture装饰器:可以使用pytest.fixture装饰器创建一个可以在测试函数中使用的参数化fixture。下面是一个示例:
import pytest @pytest.fixture(params=[1, 2, 3]) def num(request): return request.param def test_square(num): assert num ** 2 == num * num
在上面的示例中,使用@pytest.fixture装饰器创建了一个名为num的参数化fixture。通过在测试函数的参数中引用该fixture,每个参数组合都会作为单独的测试用例执行。
- 使用pytest_generate_tests钩子函数:可以使用pytest的钩子函数pytest_generate_tests来自定义参数化测试的生成方式。下面是一个示例:
import pytest def pytest_generate_tests(metafunc): if 'num' in metafunc.fixturenames: metafunc.parametrize('num', [1, 2, 3]) def test_square(num): assert num ** 2 == num * num
在上面的示例中,定义了一个pytest_generate_tests钩子函数,通过判断测试函数的参数是否存在来进行参数化。每个参数组合都会作为单独的测试用例执行。
-
使用pytest-data库:pytest-data是一个用于参数化测试的扩展库,可以通过加载外部数据文件来提供参数化测试的数据。以下是一个示例:
import pytest from pytest_data import data @pytest.mark.datafiles('test_data.csv') def test_addition(datafiles): data_file = datafiles / 'test_data.csv' for row in data(data_file): num1 = row['num1'] num2 = row['num2'] expected = row['expected'] assert num1 + num2 == expected
在上面的示例中,使用pytest-data库的data装饰器加载了一个CSV文件作为测试数据,并在测试函数中使用了这些数据进行参数化测试。
- 使用CSV或Excel文件:如果希望使用CSV或Excel文件作为测试数据进行参数化,可以使用Python的csv或openpyxl库来读取文件并生成参数组合。以下是一个示例:
import pytest import csv def read_csv(file_path): with open(file_path, 'r') as csv_file: csv_reader = csv.DictReader(csv_file) for row in csv_reader: yield row @pytest.mark.parametrize("data", read_csv("test_data.csv")) def test_multiply(data): num1 = int(data['num1']) num2 = int(data['num2']) expected = int(data['expected']) assert num1 * num2 == expected
在上面的示例中,通过read_csv函数读取CSV文件的每一行作为参数组合,并使用@pytest.mark.parametrize装饰器进行参数化测试。
- 使用pytest.mark.parametrize装饰器嵌套:可以使用pytest.mark.parametrize装饰器嵌套来进行多个参数的组合。示例如下:
import pytest @pytest.mark.parametrize("num", [1, 2]) @pytest.mark.parametrize("operation", ["add", "subtract"]) def test_calculator(num, operation): if operation == "add": result = num + num assert result == 2 * num elif operation == "subtract": result = num - num assert result == 0
在上面的示例中,使用了两个参数化装饰器,分别对num和operation进行参数化。每个参数化装饰器中的参数都会进行组合,生成不同的测试用例。
- 使用自定义参数化装饰器:除了pytest提供的装饰器,还可以自定义参数化装饰器来实现特定的参数化方式。示例如下
import pytest def custom_parametrize(*args): def decorator(func): for arg in args: func = pytest.mark.parametrize(*arg)(func) return func return decorator @custom_parametrize( ("num", [1, 2, 3]), ("operation", ["add", "subtract"]) ) def test_calculator(num, operation): if operation == "add": result = num + num assert result == 2 * num elif operation == "subtract": result = num - num assert result == 0
在上面的示例中,定义了一个自定义的参数化装饰器custom_parametrize,接受一系列参数化参数,并将其应用于测试函数。使用自定义装饰器可以实现更复杂的参数化逻辑。