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
我是 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