如何断言 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