selenium 我可以在pytest中执行多个Assert吗?

6pp0gazn  于 2023-01-05  发布在  其他
关注(0)|答案(6)|浏览(251)

我正在使用pytest进行 selenium 测试,想知道是否可以在一个测试中有多个Assert?
我调用了一个比较多个值的函数,我希望测试报告所有不匹配的值,但我遇到的问题是,使用“assert”或“pytest.fail“时,一旦发现不匹配的值,就会立即停止测试。
是否有办法让测试继续运行并报告所有不匹配的值?

2o7dmzc5

2o7dmzc51#

正如Jon Clements所评论的,您可以填充一个错误消息列表,然后Assert该列表为空,当Assert为假时显示每条消息。
具体地说,可能是这样的:

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))

原来的Assert被if语句所取代,if语句在条件不满足时将消息附加到errors列表中,然后Asserterrors列表为空(空列表为False),并使Assert消息包含errors列表中的每一条消息。
你也可以像nose文档中描述的那样做一个测试生成器,我没有找到任何描述它的pytest文档,但是我知道pytest处理这个的方式和nose完全一样。

gzjq41n4

gzjq41n42#

pytest-assume“一个pytest插件,允许每个测试多次失败”。下面是一个如何使用它的示例(摘自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)

即使有些Assert失败了,它们也会得到评估和报告:

======================================== 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 =================================
oxcyiej7

oxcyiej73#

2017年关于pytest的Pragmatic一书的作者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")
drnojrws

drnojrws4#

这里有一个叫做Delayed assert的替代方法,它与@Tryph提供的方法非常相似,并且提供了更好的堆栈跟踪。
PyPI上的delayed-assert包实现了这种方法。另请参见GitHub上的pr4bh4sh/python-delayed-assert仓库,或使用以下命令从PyPI安装:

pip install delayed-assert

您可以将任何Assert库与python-delayed-assert结合使用。请将其视为更像堆栈跟踪管理器库而不是Assert。检查this以了解示例用法
这是错误堆栈跟踪的外观,

q43xntqr

q43xntqr5#

下面是一个相当简单的方法:

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)
rn0zuynd

rn0zuynd6#

有几个选项:
1.使用pytest-check
1.使用pytest-assume
1.使用pytest夹具
其他人已经为前两个提供了示例,我将讨论最后一个选项。
pytest文档中提供的示例稍微详细一些,我将提供一个更简单的示例。

#!/usr/bin/env python3
"""
Multiple independent asserts using class-scope fixture
"""

import pytest

@pytest.fixture(scope="class")
def data():
    """
    Create data for test.

    Using scope=class, this fixture is created once per class. That
    means each test should exercise care not to alter the fixture data,
    or subsequent tests might fail.
    """
    fixture_data = dict(a=1, b=2, c=3)
    print(f"(data fixture created at {id(fixture_data)}) ", end="")
    return fixture_data

class TestItWithFailures:
    def test_a_value(self, data):
        assert data["a"] == 1
        # Modify the data will cause test failure in subsequent tests
        data["b"] = 200
        data["c"] = 300

    def test_b_value(self, data):
        # Failed because of previous modification
        assert data["b"] == 2

    def test_c_value(self, data):
        # Failed because of previous modification
        assert data["c"] == 3

class TestWithSuccess:
    def test_a_value(self, data):
        assert data["a"] == 1

    def test_b_value(self, data):
        assert data["b"] == 2

    def test_c_value(self, data):
        assert data["c"] == 3

输出

test_it.py::TestItWithFailures::test_a_value (data fixture created at 4366616320) PASSED
test_it.py::TestItWithFailures::test_b_value FAILED
test_it.py::TestItWithFailures::test_c_value FAILED
test_it.py::TestWithSuccess::test_a_value (data fixture created at 4372781312) PASSED
test_it.py::TestWithSuccess::test_b_value PASSED
test_it.py::TestWithSuccess::test_c_value PASSED

注解

  • 每个类都是一个独立的测试,类中的每个函数都是一个独立的Assert。这样,我们就实现了多个独立的Assert。
  • 注意不要改变数据固定器,否则会影响TestItWithFailures类中的后续测试。

相关问题