首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >pytest.mark.parametrize中的可选参数

pytest.mark.parametrize中的可选参数
EN

Stack Overflow用户
提问于 2020-05-16 17:19:17
回答 3查看 687关注 0票数 6

我用pytest框架做了一个长时间的测试。代码如下:

代码语言:javascript
复制
@pytest.fixture(scope='function')
def my_setup():
        execute_setup_actions()

@pytest.mark.parametrize('name, arg1', [
        ('test_1', 1),
        ...
        ('test_100', 100),
])
def test_mine(name, arg1):
         execute_test_case(arg1)

现在,我需要一个可选的参数arg2,用于在用@pytest.mark.parametrize编写的一个新测试中使用的my_setup治具my_setup(arg2=None)。当然,我可以将'name, arg1, arg2'放在parametrize中,并为其他100个测试添加None参数值,但是还有其他方法可以更好地完成这样的任务吗?

谢谢!

EN

回答 3

Stack Overflow用户

发布于 2022-07-12 05:11:11

将参数传递到夹具中的最标准(即规范)方法是使用pytest的间接论点

您可以将这个新参数添加到所有参数元组中,或者如果希望避免它,可以创建一个与第一个方法相同的新测试方法,但它只包含新的元组,如下所示:

代码语言:javascript
复制
import pytest


def execute_setup_actions(fixture_param):
    print(f"entered execute_setup_actions with {fixture_param}")


@pytest.fixture(scope='function')
def my_setup(request):
    fixture_param = getattr(request, 'param', None)  # or your default value
    execute_setup_actions(fixture_param)
    return fixture_param


def execute_test_case(arg1, arg2):
    print(f"entered execute_test_case with {arg1}, {arg2}")


@pytest.mark.parametrize('name, arg1', [
    ('test_1', 1),
    ('test_100', 100),
])
def test_mine(my_setup, name, arg1):
    execute_test_case(arg1, my_setup)


@pytest.mark.parametrize('my_setup, name, arg1', [
    (20, 'test_101', 1),
    (2020, 'test_102', 100),
], indirect=["my_setup"])
def test_mine_with_extra_parameter(my_setup, name, arg1):
    execute_test_case(arg1, my_setup)
票数 1
EN

Stack Overflow用户

发布于 2022-07-10 23:46:41

如果您想将一个参数传递给一个夹具,您应该使用工厂作为模式,如解释的在文件中

代码语言:javascript
复制
@pytest.fixture(scope='function')
def my_setup():
    def _my_setup(arg2=None)
        execute_setup_actions(arg2)

    return _my_setup

然后,在你的测试中:

代码语言:javascript
复制
@pytest.mark.parametrize('name, arg1', [
        ('test_1', 1),
        ...
        ('test_100', 100),
])
def test_mine(name, arg1, my_setup):
    my_setup(arg2)
    execute_test_case(arg1)

与您建议的将arg2添加到参数化标记中不同,您可以只编写另一个测试,但是,由于arg2只有一个值,所以不需要将其参数化:

代码语言:javascript
复制
@pytest.mark.parametrize('name, arg1', [
        ('test_1', 1),
        ...
        ('test_100', 100),
])
def test_mine1(name, arg1):
         execute_test_case(arg1)


def test_mine2(name):
         execute_test_case(arg1, arg2)

请注意,在第二个测试中没有名称夹具的值,因为它不在第一个测试中使用(下面将详细介绍)。

现在,您的代码有一些不一致之处:

  1. 没有使用my_setup夹具。您应该添加autouse=True选项或将其添加到测试签名中。
  2. 您没有在测试中使用name参数。
  3. name参数会是测试id吗?然后,您可以在参数标记上使用id选项(更多这里)。

因此,根据您的需要和我看到的问题,我会这样重构您的测试:

代码语言:javascript
复制
names_list = ['test_1' ... 'test_100']
arg1_list = [1 ... 100]

@pytest.mark.parametrize('arg1', arg1_list, ids=names_list)
def test_mine1(arg1):
         execute_test_case(arg1)


def test_mine2():
         execute_test_case(arg1, arg2)
票数 0
EN

Stack Overflow用户

发布于 2022-07-16 14:45:39

下面是一种进行灵活的表驱动测试的方法。

代码语言:javascript
复制
import pytest

def convert(input: str, options: dict) -> str:
    if options:
        return globals()[options](input)
    return lower(input)

def upper(input: str) -> str:
    return input.upper()

def lower(input: str) -> str:
    return input.lower()

class TestClass:
    tests = [
        {"input": "FOO", "expected": "foo"},
        {"input": "bar", "expected": "BAR", "options": "upper"},
        {"input": "BAZ", "expected": "baz", "options": "lower"},
    ]

    @pytest.mark.parametrize('tests', tests)
    def test(self, tests):
        actual = convert(tests["input"], tests.get("options"))
        assert actual == tests["expected"]
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61840755

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档