简体   繁体   English

带有自定义 id 函数的 pytest 参数化测试

[英]pytest parameterized test with custom id function

I have a parameterized test which takes str , and dict as an argument and so the name look pretty weird if I allow pytest to generate ids.我有一个参数化测试,它接受strdict作为参数,所以如果我允许 pytest 生成 id,这个名字看起来很奇怪。

I want to generate custom ids using a function, however it seems it's not working as intended.我想使用函数生成自定义 ID,但它似乎没有按预期工作。

def id_func(param):
    if isinstance(param, str):
        return param


@pytest.mark.parametrize(argnames=('date', 'category_value'),
                         argvalues=[("2017.01", {"bills": "0,10", "shopping": "100,90", "Summe": "101,00"}),
                                    ("2017.02", {"bills": "20,00", "shopping": "10,00", "Summe": "30,00"})],
                         ids=id_func)
def test_demo(date, category_value):
    pass

I was thinking it would return something like this我以为它会返回这样的东西

test_file.py::test_demo[2017.01] PASSED
test_file.py::test_demo[2017.02] PASSED

but it's returning this.但它正在返回这个。

test_file.py::test_demo[2017.01-category_value0] PASSED
test_file.py::test_demo[2017.02-category_value1] PASSED

Could someone tell me what's wrong with this, or is there any way to achieve this?有人可以告诉我这有什么问题,或者有什么方法可以实现这一目标?

Update:更新:

I realize what's the issue, if_func will be called for each parameter and if I won't return str for any parameter default function will be called.我意识到问题是什么,每个参数都会调用 if_func ,如果我不为任何参数返回str ,则将调用默认函数。 I have fix but that's also ugly.我有修复,但这也很丑陋。

def id_func(param):
    if isinstance(param, str):
        return param
    return " "

Now it returns something like this,现在它返回这样的东西,

test_file.py::test_demo[2017.01- ] PASSED
test_file.py::test_demo[2017.02- ] PASSED

The problem is even If I return empty string (ie return "" )it takes the default representation.问题是即使我返回空字符串(即return "" ),它也会采用默认表示。 Could someone let me know why?有人可以让我知道为什么吗?

One way is to move your argvalues to another variable and write your test like this:一种方法是将您的argvalues移动到另一个变量并像这样编写测试:

import pytest


my_args = [
      ("2017.01", {"bills": "0,10", "shopping": "100,90", "Summe": "101,00"}),
      ("2017.02", {"bills": "20,00", "shopping": "10,00", "Summe": "30,00"})
]


@pytest.mark.parametrize(
    argnames=('date', 'category_value'), argvalues=my_args,
    ids=[i[0] for i in my_args]
)
def test_demo(date, category_value):
    pass

Test execution:测试执行:

$ pytest -v tests.py 
================= test session starts =================
platform linux2 -- Python 2.7.12, pytest-3.2.1, py-1.4.34, pluggy-0.4.0 -- /home/kris/.virtualenvs/2/bin/python2
cachedir: .cache
rootdir: /home/kris/projects/tmp, inifile:
collected 2 items                                      

tests.py::test_demo[2017.01] PASSED
tests.py::test_demo[2017.02] PASSED

============== 2 passed in 0.00 seconds ===============

I think it's not possible with a function ( idfn in your case), because if it's not generating label for an object the default pytest representation is used.我认为使用函数(在您的情况下为idfn )是不可能的,因为如果它不为对象生成标签,则使用默认的 pytest 表示。
Check pytest site for details.查看pytest 站点以获取详细信息。

Alternatively you can also use a list comprehension to generate your ids as follows:或者,您也可以使用列表理解来生成您的 id,如下所示:

import pytest


values = [
    ("2017.01", {"bills": "0,10", "shopping": "100,90", "Summe": "101,00"}),
    ("2017.02", {"bills": "20,00", "shopping": "10,00", "Summe": "30,00"})
]
value_ids = [e[0] for e in values]


@pytest.mark.parametrize('date,category_value', values, ids=value_ids
)
def test_demo(date, category_value):
    pass

Assuming these tests are in test_file.py at the root of your directory, if you run pytest test_file.py --co -q , you will get the following output:假定这些测试是在test_file.py在你的根目录下,如果你运行pytest test_file.py --co -q ,你将得到以下的输出:

test_file.py::test_demo[2017.01]
test_file.py::test_demo[2017.02]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM