我可以在 pytest 中执行多个断言吗?

Can I perform multiple assertions in pytest?

我正在使用 pytest 进行 selenium 测试,想知道是否可以在单个测试中使用多个断言?

我调用了一个比较多个值的函数,我希望测试报告所有不匹配的值。我遇到的问题是,一旦发现不匹配的值,使用 "assert" 或 "pytest.fail" 就会停止测试。

有没有办法让测试继续进行 运行 并报告所有不匹配的值?

正如 Jon Clements 评论的那样,您可以填写错误消息列表,然后断言该列表为空,并在断言为假时显示每条消息。

具体来说,可能是这样的:

def test_something(self):
    errors = []

    # replace assertions by conditions
    if not condition_1:
        errors.append("an error message")
    if not condition_2:
        errors.append("an other error message")

    # assert no error message has been registered, else print messages
    assert not errors, "errors occured:\n{}".format("\n".join(errors))

原始断言被 if 语句替换,这些语句将消息附加到 errors 列表以防不满足条件。 然后断言 errors 列表为空(空列表为 False)并使断言消息包含 errors 列表中的每条消息。


您还可以按照 nose documentation 中的描述制作测试生成器。我没有找到任何描述它的 pytest 文档,但我知道 pytest 处理这个的方式与 nose 完全相同。

这是另一种方法,称为 Delayed assert,它与 @Tryph 提供的非常相似,并提供更好的堆栈跟踪。

GitHub 上的 delayed-assert package on PyPI implements this approach. See also the pr4bh4sh/python-delayed-assert 存储库,或使用以下方法从 PyPI 安装:

pip install delayed-assert

您可以(可能)将任何断言库与 python-delayed-assert 结合使用。将其视为堆栈跟踪管理器库而不是断言。检查 this 例如使用

这是错误堆栈跟踪的样子,

pytest-assume"a pytest plugin that allows multiple failures per test"。这是您将如何使用它的示例(取自 README):

import pytest

@pytest.mark.parametrize(('x', 'y'), [(1, 1), (1, 0), (0, 1)])
def test_simple_assume(x, y):
    pytest.assume(x == y)
    pytest.assume(True)
    pytest.assume(False)

即使一些断言失败,它们都会得到评估和报告:

======================================== FAILURES =========================================
_________________________________ test_simple_assume[1-1] _________________________________
>    pytest.assume(False)
test_assume.py:7

y          = 1
x          = 1
----------------------------------------
Failed Assumptions:1
_________________________________ test_simple_assume[1-0] _________________________________
>    pytest.assume(x == y)
test_assume.py:5

y          = 0
x          = 1
>    pytest.assume(False)
test_assume.py:7

y          = 0
x          = 1
----------------------------------------
Failed Assumptions:2
_________________________________ test_simple_assume[0-1] _________________________________
>    pytest.assume(x == y)
test_assume.py:5

y          = 1
x          = 0
>    pytest.assume(False)
test_assume.py:7

y          = 1
x          = 0
----------------------------------------
Failed Assumptions:2
================================ 3 failed in 0.02 seconds =================================

2017 年关于 pytest 的实用书籍的作者 Brian Okken 提供了另一个库。 https://pythontesting.net/books/pytest/ https://github.com/okken/pytest-check

import pytest_check as check

def test_example():
    a = 1
    b = 2
    c = [2, 4, 6]
    check.greater(a, b)
    check.less_equal(b, a)
    check.is_in(a, c, "Is 1 in the list")
    check.is_not_in(b, c, "make sure 2 isn't in list")

这是一个相当简单的方法:


import pytest

def test_sample(texts):
    flag = True
    for text in texts:
        if text != "anything":
            flag = False
    if flag==False:
        pytest.fail("text did not match", pytrace=True)