Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 是否可以全局设置pytest'的默认'ids'函数;什么是参数化?_Python_Pytest - Fatal编程技术网

Python 是否可以全局设置pytest'的默认'ids'函数;什么是参数化?

Python 是否可以全局设置pytest'的默认'ids'函数;什么是参数化?,python,pytest,Python,Pytest,pytest.mark.parametrize接受可调用的ids参数,如下所示: def test_id_builder(arg): if isinstance(arg, int): return str(arg) ... # more logic @pytest.mark.parametrize('value', [1, 2], ids=test_id_builder) def test_whatever(value): assert value &

pytest.mark.parametrize
接受可调用的
ids
参数,如下所示:

def test_id_builder(arg):
    if isinstance(arg, int):
        return str(arg)

    ... # more logic

@pytest.mark.parametrize('value', [1, 2], ids=test_id_builder)
def test_whatever(value):
    assert value > 0

这将生成两个测试用例,分别ID为“1”和“2”。问题是,我有很多测试,组织在多个类和文件中。因此,我想将
test\u id\u builder
全局设置为项目中所有参数化测试的
ids
函数。有办法做到这一点吗?

没有办法全局设置ID。但是您可以使用从一些
其他
夹具生成测试。该
其他
夹具的作用范围可限定为
会话
,总体上将模拟预期行为。

您可以自定义
参数化

import pytest

def id_builder(arg):
    if isinstance(arg, int):
        return str(arg) * 2

def custom_parametrize(*args, **kwargs):
    kwargs.setdefault('ids', id_builder)
    return pytest.mark.parametrize(*args, **kwargs)

@custom_parametrize('value', [1, 2])
def test_whatever(value):
    assert value > 0
为了避免在任何地方重写
pytest.mark.parametrize
custom\u parametrize
,请使用此众所周知的解决方法:

old_parametrize = pytest.mark.parametrize

def custom_parametrize(*args, **kwargs):
    kwargs.setdefault('ids', id_builder)
    return old_parametrize(*args, **kwargs)

pytest.mark.parametrize = custom_parametrize
只需实现一个自定义挂钩。在您的
conftest.py
中:

def pytest_make_parametrize_id(config, val, argname):
    if isinstance(val, int):
        return f'{argname}={val}'
    if isinstance(val, str):
        return f'text is {val}'
    # return None to let pytest handle the formatting
    return None
示例测试:

import pytest


@pytest.mark.parametrize('n', range(3))
def test_int(n):
    assert True

@pytest.mark.parametrize('s', ('fizz', 'buzz'))
def test_str(s):
    assert True


@pytest.mark.parametrize('c', (tuple(), list(), set()))
def test_unhandled(c):
    assert True
检查测试参数化:

$pytest-q--仅收集
test\u spam.py::test\u int[n=0]
test\u spam.py::test\u int[n=1]
test_spam.py::test_int[n=2]
test_spam.py::test_str[文本为fizz]
test_spam.py::test_str[文本是buzz]
test\u spam.py::test\u未处理[c0]
test\u spam.py::test\u未处理[c1]
test\u spam.py::test\u未处理[c2]
0.06秒内未运行任何测试

这感觉像是糟糕的设计。。。但我要了。现在看来这是一个干净的解决方案。但是有一件事:
returnval
仅在
val
是字符串时有效;根据文档,让pytest处理的正确方法是返回
None
@aranfey很高兴我能帮上忙!事实上,我在回答中犯了一个错误<如果要将arg表示委托给
pytest
,则应将code>return val
替换为
return None
。将更新答案。