如何告知pytest某个函数失败的断言是正确行为?
背景:在我的一个项目中,我使用了pytest
,并且有一个辅助函数,这个函数在很多测试中负责最后的断言。所以代码大概是这样的:
tsthelper.py:
def check(obj1, obj2, *args):
# do stuff calculate (using args) from the objects two strings str1 and str2
assert str1 == str2
test_arg1.py:
from tsthelper import check
def test_arg1_():
# Setup obj1 and obj2
check(obj1, obj2, arg1):
def test_arg2_():
# Setup obj1 and obj2
check(obj1, obj2, arg2):
...
def test_no_arg1_should_fail():
# Setup obj1 and obj2
check(obj1, obj2):
所以,大部分函数应该是用来进行断言的,只有最后一个应该失败。
我觉得使用xfail
这个功能并不是个好主意,因为这样的话,pytest
会把失败的情况单独计算。但我想要的是,最后一个函数的失败被视为正确的行为,这样pytest
在统计时应该把它算作成功。
我需要给这个失败的函数加上什么装饰器,才能让它被当作成功处理呢?
1 个回答
0
不同的函数专门测试不同的行为,这样做的目的是为了让调试变得更简单,测试覆盖面更广,而且在使用测试驱动开发(TDD)时更灵活。
如果你想让某个测试中的 check()
断言失败,可以试试在测试里使用 pytest.raises
。
import pytest
from tsthelper import check
def test_no_arg1_should_fail():
# Setup obj1 and obj2
with pytest.raises(AssertionError):
check(obj1, obj2)
这样,当 check()
方法抛出一个断言异常时,测试函数就会把这个当作正确的行为,从而通过测试。
更好的方法
下面是一些更符合 Python 风格的替代方案,可以让你的测试保持干净且易于理解。
- 修改
check()
函数,只返回 str1 是否等于 str2 的结果,然后每个测试函数明确地断言check()
的结果是 True 还是 False。
def check(obj1, obj2, *args):
return str1 == str2
def my_test():
results = check(obj1, obj2, arg2)
assert True == results
- 使用 pytest 参数化: 从你分享的代码来看,你是在用不同的参数测试同一个函数。一个很好的方法是使用 pytest 参数化,这样可以遵循 DRY 原则,避免重复代码。
没有参数化的代码
def check_add(a,b):
return a + b
def test_positive_numbers():
assert check_add(3, 2) == 5
def test_negative_numbers():
assert check_add(-2, -2) == -4
def test_zero():
assert check_add(0, 0) == 0
使用参数化的代码
@pytest.mark.parametrize("a, b, expected", [
(3, 2, 5),
(-2, -2, -4),
(0, 0, 0),
])
def test_ints(a, b, expected):
assert check_add(a, b) == expected
这样做基本上会对所有不同的输入运行你的函数,作为不同的测试,从而减少代码重复。
你可以在 这里 了解更多信息。