pytest:参数化测试与显式测试

pytest: paramaterized tests vs explicit tests

我是 pytest 的新手,我想澄清一些关于参数化测试的困惑。

使用单个参数化测试函数或仅 'input' 不同的多个显式测试更好(即更清晰、更 DRY、更易于维护)?

让我举个例子,希望能更好地解释我的观点:

假设我们编写了一个简单的函数,merge_sort,我们想使用各种输入来测试它,例如包括负数、重复数字、浮点数等。

正在编写多个显式测试:

def test_merge_sort():
    unsorted = [2, 1, 3]
    expected = [1, 2, 3]

    assert merge_sort(unsorted) == expected

def test_merge_sort_negative():
    unsorted = [-2, -1, -3]
    expected = [-3, -2, -1]

    assert merge_sort(unsorted) == expected

def test_merge_sort_including_zero():
    unsorted = [2, 0, 1]
    expected = [0, 1, 2]

    assert merge_sort(unsorted) == expected

def test_merge_sort_repeated_number():
    unsorted = [0, 1, 0]
    expected = [0, 0, 1]

    assert merge_sort(unsorted) == expected

def test_merge_sort_float():
    unsorted = [0.1, 0.3, 0.2]
    expected = [0.1, 0.2, 0.3]

    assert merge_sort(unsorted) == expected

或者,编写单个参数化测试:

@pytest.mark.parametrize("unsorted,expected", [
    ([2,1,3], [1,2,3]),
    ([-2,-1,-3], [-3,-2,-1]),
    ([2,0,1], [0,1,2]),
    ([0,1,0], [0,0,1]),
    ([0.1,0.3,0.2], [0.1,0.2,0.3]),
])
def test_merge_sort(unsorted, expected):
    assert merge_sort(unsorted) == expected

我最初的想法是,多个显式测试更清晰,更易于维护,如果有失败,你会得到一个描述性的函数名称,表明被测的具体情况。但是,参数化测试更 DRY,提取测试数据作为其他测试的夹具可能更容易(即使用相同的数据来测试 quick_sort 函数)。

也许我在 pytest 文档中遗漏了什么可以回答这个问题?

在此先感谢您的帮助!

失败消息将包含所有参数化值,因此您可以向参数添加描述文本:

@pytest.mark.parametrize("description,unsorted,expected", [
    ("positive", [2,1,3], [1,2,3]),
    ("negative", [-2,-1,-3], [-3,-2,-1]),
    ("including zero", [2,0,1], [0,1,2]),
    ("duplicate values", [0,1,0], [0,0,1]),
    ("floats", [0.1,0.3,0.2], [0.1,0.2,0.3]),
])
def test_merge_sort(description, unsorted, expected):
    assert merge_sort(unsorted) == expected