简体   繁体   English

自定义 pytest 参数化测试名称

[英]Customizing pytest parameterized test name

I've the following tests:我有以下测试:

@pytest.mark.parametrize(
    "nums",
    [[3, 1, 5, 4, 2], [2, 6, 4, 3, 1, 5], [1, 5, 6, 4, 3, 2]]
)
def test_cyclic_sort(nums):
    pass


@pytest.mark.parametrize(
    "nums, missing",
    [([4, 0, 3, 1], 2)]
)
def test_find_missing_number(nums, missing):
    pass

I'd like to customize the test names to include the input array.我想自定义测试名称以包含输入数组。 I've read the pytest docs , and this question and this question , but none answer the following questions:我已经阅读了pytest 文档,以及这个问题这个问题,但没有人回答以下问题:

  1. What is passed to the id func?传递给 id 函数的是什么? In my code above, the first test takes one parameter, the second takes two.在我上面的代码中,第一个测试需要一个参数,第二个测试需要两个。
  2. pytest docs use a top-level function for id, whereas I'd like to put my tests in a class and use a @staticmethod . pytest 文档使用顶级 function 作为 id,而我想将我的测试放在 class 中并使用@staticmethod Trying to reference the static method with TestClass.static_method from inside TestClass gives an error in PyCharm;尝试从TestClass内部使用TestClass.static_method引用 static 方法会导致 PyCharm 出现错误; what is the correct syntax for doing this?这样做的正确语法是什么?

Edit: Created https://github.com/pytest-dev/pytest/issues/8448 .编辑:创建https://github.com/pytest-dev/pytest/issues/8448

When using a callable for the ids keyword, it will be called with a single argument: the value of the test parameter being parametrized.当为ids关键字使用可调用对象时,将使用单个参数调用它:被参数化的测试参数的值。 The callable ids return a string, which will be used in square brackets as the test name suffix.可调用的ids返回一个字符串,该字符串将在方括号中用作测试名称后缀。

If the test is parametrizing over multiple values, the function will still be called with a single argument, but it will be called multiple times per test.如果测试对多个值进行参数化,则 function 仍将使用单个参数调用,但每次测试将调用多次。 The generated name will be joined with dashes, something like生成的名称将与破折号相连,例如

"-".join([idfunc(val) for val in parameters])

For example:例如:

test_something[val1-val2-val3]

Here is the join in the pytest source . 这是 pytest 源中的连接

To use a static method, this syntax works:要使用 static 方法,此语法有效:

class TestExample:

    @staticmethod
    def idfunc(val):
        return f"foo{val}"

    @pytest.mark.parametrize(
        "x, y",
        [
            [1, 2],
            ["a", "b"],
        ],
        ids=idfunc.__func__,
    )
    def test_vals(self, x, y):
        assert x
        assert y

This will generate two tests, calling idfunc four times as described above.这将生成两个测试,如上所述调用idfunc四次。

TestExample::test_vals[foo1-foo2]
TestExample::test_vals[fooa-foob]

I like wims answer, and this is intended as a comment to his answer (I dont have the points to make a comment).我喜欢wims的回答,这是对他的回答的评论(我没有发表评论的要点)。 This seems more pythonic to me.这对我来说似乎更pythonic。 It also helps avoid using a static method.它还有助于避免使用 static 方法。

class TestExample:
    @pytest.mark.parametrize(
        "x, y",
        [
            [1, 2],
            ["a", "b"],
        ],
        ids= lamba val : f"foo{val}"
    )
    def test_vals(self, x, y):
        assert x
        assert y

This will have the same output:这将具有相同的 output:

TestExample::test_vals[foo1-foo2]
TestExample::test_vals[fooa-foob]

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

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