如何断言 python 中所有失败的断言
How to assert all asserts failed in python
我正在尝试编写如何不在 pytest 中编写测试的示例。为此,我希望能够以某种方式 mod 测试函数,以便它们在任何断言通过时失败。使用装饰器的一个断言很容易:
def faulty_test(test_fn):
def new_test_fn():
try:
test_fn()
except AssertionError:
pass
else:
raise AssertionError
return new_test_fn
@faulty_test
def test_sth():
assert 1 == 2
但我想为具有任意数量断言的函数执行此操作。如果任何断言通过,则测试应该失败。它不一定是装饰器
我猜它不一定是多个断言。你可以这样写:
assert a == b or c == d or # so on
任何条件为真都会导致断言通过。
或许你应该这样想:在异常点,执行离开try块,进入except块。您不能,至少以我能想到的任何简单方式,re-enter except 块中的 try 块。
也许我误解了这个问题,但你不能简单地用这些断言的反面替换你的断言吗?如果你想断言某件事是假的,你可以:
assert not (1 == 2)
如果由于某种原因你正在处理这样一种情况,你假设给定的函数由于某种原因总是会失败他们的断言并且你无法改变它,似乎没有任何方法可以确保所有断言 运行,因为断言的设计是在失败时有意立即中止。
如果您 "number" 断言,捕捉到一个值大于 0 的断言意味着之前的断言已通过。
def faulty_test(test_fn):
def new_test_fn():
try:
test_fn()
except AssertionError as exc:
if exc.args[0] > 0:
# Assertions 0 through exc.args[0]-1 all passed
raise AssertionError
else:
raise AssertionError
return new_test_fn
@faulty_test
def test_sth():
assert 1 == 2, 0
assert 2 == 3, 1
assert 3 == 4, 2
您可能应该在函数代码中使用 _debug
或其他(隐藏)参数来处理它。然后你可以在上面使用装饰器。我会做什么:
def deco(inF):
def wrapper(*args, **kwargs):
kwargs['_debug'] = True
output = inF(*args, **kwargs)
#print(output)
for i, _ in enumerate(zip(*output)):
condition, msg = _
# this will raise the first passed assert. Otherwise loop again to print all "passed" assertions, then raise
if not condition:
raise AssertionError('Condition {} succeded: {} is False'.format(1 + i, msg))
return output
return wrapper
@deco
def f(i, j , k, _debug=False):
cond1, msg1 = i == 1, 'i is not 1'
cond2, msg2 = j == 2, 'j is not 2'
cond3, msg3 = k == 3, 'k is not 3'
assert cond1 or _debug, msg1
assert cond2 or _debug, msg2
assert cond3 or _debug, msg3
if _debug:
return (cond1, cond2, cond3), (msg1, msg2, msg3)
return i + j + k
f(1,1,5)
>>AssertionError: Condition 2 succeded: j is not 2 is False
我正在尝试编写如何不在 pytest 中编写测试的示例。为此,我希望能够以某种方式 mod 测试函数,以便它们在任何断言通过时失败。使用装饰器的一个断言很容易:
def faulty_test(test_fn):
def new_test_fn():
try:
test_fn()
except AssertionError:
pass
else:
raise AssertionError
return new_test_fn
@faulty_test
def test_sth():
assert 1 == 2
但我想为具有任意数量断言的函数执行此操作。如果任何断言通过,则测试应该失败。它不一定是装饰器
我猜它不一定是多个断言。你可以这样写:
assert a == b or c == d or # so on
任何条件为真都会导致断言通过。
或许你应该这样想:在异常点,执行离开try块,进入except块。您不能,至少以我能想到的任何简单方式,re-enter except 块中的 try 块。
也许我误解了这个问题,但你不能简单地用这些断言的反面替换你的断言吗?如果你想断言某件事是假的,你可以:
assert not (1 == 2)
如果由于某种原因你正在处理这样一种情况,你假设给定的函数由于某种原因总是会失败他们的断言并且你无法改变它,似乎没有任何方法可以确保所有断言 运行,因为断言的设计是在失败时有意立即中止。
如果您 "number" 断言,捕捉到一个值大于 0 的断言意味着之前的断言已通过。
def faulty_test(test_fn):
def new_test_fn():
try:
test_fn()
except AssertionError as exc:
if exc.args[0] > 0:
# Assertions 0 through exc.args[0]-1 all passed
raise AssertionError
else:
raise AssertionError
return new_test_fn
@faulty_test
def test_sth():
assert 1 == 2, 0
assert 2 == 3, 1
assert 3 == 4, 2
您可能应该在函数代码中使用 _debug
或其他(隐藏)参数来处理它。然后你可以在上面使用装饰器。我会做什么:
def deco(inF):
def wrapper(*args, **kwargs):
kwargs['_debug'] = True
output = inF(*args, **kwargs)
#print(output)
for i, _ in enumerate(zip(*output)):
condition, msg = _
# this will raise the first passed assert. Otherwise loop again to print all "passed" assertions, then raise
if not condition:
raise AssertionError('Condition {} succeded: {} is False'.format(1 + i, msg))
return output
return wrapper
@deco
def f(i, j , k, _debug=False):
cond1, msg1 = i == 1, 'i is not 1'
cond2, msg2 = j == 2, 'j is not 2'
cond3, msg3 = k == 3, 'k is not 3'
assert cond1 or _debug, msg1
assert cond2 or _debug, msg2
assert cond3 or _debug, msg3
if _debug:
return (cond1, cond2, cond3), (msg1, msg2, msg3)
return i + j + k
f(1,1,5)
>>AssertionError: Condition 2 succeded: j is not 2 is False