pytest中的参数化测试具有针对不同测试功能的不同标记

问题描述

我目前正在尝试在以下情况下使用pytest的参数化功能

我有多个功能,应该使用一组通用的测试用例进行测试。根据测试的功能,相同的测试用例应通过或xfail。我想出一个愚蠢的例子来说明这一点:

import pytest


# Functions to test
def sum_int(a,b):
    assert isinstance(a,int)
    assert isinstance(b,int)
    return a + b


def sum_any(a,b):
    return a + b


# Universal test cases
TESTCASES = [
    "a,b,result",[
        (1,1,2),("a","a","aa")
        ]
    ]


class Tests:
    @pytest.mark.parametrize(*TESTCASES,ids=["int_pass","str_fail"])
    def test_sum_int(self,a,result):
        assert sum_int(a,b) == result

    @pytest.mark.parametrize(*TESTCASES,"str_pass"])
    def test_sum_any(self,result):
        assert sum_any(a,b) == result


不幸的是,似乎不可能像使用ID一样仅将附加标记(如pytest.mark.xfail(reason=AssertionError)传递到parametrize())。

# Does not work
@pytest.mark.parametrize(*TESTCASES,"str_fail"],marks=[None,pytest.mark.xfail(reason=AssertionError)])
def test_sum_int(self,result):
    assert sum_int(a,b) == result

什么是实现此目标的好方法

解决方法

如果您尝试仅标记字符串测试的总和,则可以这样做:

# Universal test cases
TESTCASES = [
    "a,b,result",[
        (1,1,2),pytest.mark.xfail(("a","a","aa"))
        ]
    ]

在这里https://docs.pytest.org/en/2.8.7/parametrize.html#:~:text=#%20content%20of%20test_expectation.py

,

我不得不发现我的问题的答案相对简单。 pytest.param 机制允许为特定测试用例指定标记:

@pytest.mark.parametrize(
    TESTCASES[0],[
        pytest.param(*args,marks=marks)
        for args,marks
        in zip(TESTCASES[1],[[],[pytest.mark.xfail(reason=AssertionError)]])
    ],ids=["int_pass","str_fail"],)
def test_sum_int(self,a,result):
    assert sum_int(a,b) == result