pytest文档36-断言失败后还能继续执行pytest-assume

Posted 上海-悠悠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了pytest文档36-断言失败后还能继续执行pytest-assume相关的知识,希望对你有一定的参考价值。

前言

pytest的断言失败后,后面的代码就不会执行了,通常一个用例我们会写多个断言,有时候我们希望第一个断言失败后,后面能继续断言。
pytest-assume插件可以解决断言失败后继续断言的问题。github地址https://github.com/astraw38/pytest-assume

环境准备

先安装pytest-assume依赖包

pip install pytest-assume

遇到问题

以下是一个简单案例,输入的测试数据有3种,我们需要断言同时满足三种情况

  • x == y
  • x+y > 1
  • x > 1
import pytest
# 上海-悠悠

@pytest.mark.parametrize(('x', 'y'),
                         [(1, 1), (1, 0), (0, 1)])
def test_simple_assume(x, y):
    print("测试数据x=%s, y=%s" % (x, y))
    assert x == y
    assert x+y > 1
    assert x > 1

运行结果

D:\\demo\\test_yoyo.py:9: AssertionError


================================== FAILURES ===================================
___________________________ test_simple_assume[1-1] ___________________________

x = 1, y = 1

    @pytest.mark.parametrize(('x', 'y'),
                             [(1, 1), (1, 0), (0, 1)])
    def test_simple_assume(x, y):
        print("测试数据x=%s, y=%s" % (x, y))
        assert x == y
        assert x+y > 1
>       assert x > 1
E       assert 1 > 1

D:\\soft\\code\\pytest_api_2020_03\\demo\\test_yoyo.py:11: AssertionError
___________________________ test_simple_assume[1-0] ___________________________

x = 1, y = 0

    @pytest.mark.parametrize(('x', 'y'),
                             [(1, 1), (1, 0), (0, 1)])
    def test_simple_assume(x, y):
        print("测试数据x=%s, y=%s" % (x, y))
>       assert x == y
E       assert 1 == 0

D:\\soft\\code\\pytest_api_2020_03\\demo\\test_yoyo.py:9: AssertionError
___________________________ test_simple_assume[0-1] ___________________________

x = 0, y = 1

    @pytest.mark.parametrize(('x', 'y'),
                             [(1, 1), (1, 0), (0, 1)])
    def test_simple_assume(x, y):
        print("测试数据x=%s, y=%s" % (x, y))
>       assert x == y
E       assert 0 == 1

D:\\demo\\test_yoyo.py:9: AssertionError
========================== 3 failed in 0.26 seconds ===========================

如果第一个断言就失败了,后面的2个断言都不会执行了

pytest-assume使用案例

使用pytest.assume断言

import pytest
# 上海-悠悠

@pytest.mark.parametrize(('x', 'y'),
                         [(1, 1), (1, 0), (0, 1)])
def test_simple_assume(x, y):
    print("测试数据x=%s, y=%s" % (x, y))
    pytest.assume(x == y)
    pytest.assume(x+y > 1)
    pytest.assume(x > 1)
    print("测试完成!")

运行结果

================================== FAILURES ===================================
___________________________ test_simple_assume[1-1] ___________________________

tp = <class 'pytest_assume.plugin.FailedAssumption'>
value = FailedAssumption('\\demo\\\\test_yoyo.py:11: AssumptionFailure\\n>>\\tpytest.assume(x > 1)\\n
AssertionError: assert False\\n\\n',)
tb = <traceback object at 0x00000216CA579B08>

    def reraise(tp, value, tb=None):
        if value is None:
            value = tp()
        if value.__traceback__ is not tb:
>           raise value.with_traceback(tb)
E           pytest_assume.plugin.FailedAssumption: 
E           1 Failed Assumptions:
E           
E           ..\\..\\..\\..\\..\\soft\\code\\pytest_api_2020_03\\demo\\test_yoyo.py:11: AssumptionFailure
E           >>	pytest.assume(x > 1)
E           AssertionError: assert False

E:\\python36\\lib\\site-packages\\six.py:685: FailedAssumption
___________________________ test_simple_assume[1-0] ___________________________

tp = <class 'pytest_assume.plugin.FailedAssumption'>
value = FailedAssumption('\\demo\\\\test_yoyo.py:9:...st_api_2020_03\\\\demo\\\\test_yoyo.py:11: 
AssumptionFailure\\n>>\\tpytest.assume(x > 1)\\nAssertionError: assert False\\n\\n',)
tb = <traceback object at 0x00000216CA579448>

    def reraise(tp, value, tb=None):
        if value is None:
            value = tp()
        if value.__traceback__ is not tb:
>           raise value.with_traceback(tb)
E           pytest_assume.plugin.FailedAssumption: 
E           3 Failed Assumptions:
E           
E           ..\\..\\..\\..\\..\\soft\\code\\pytest_api_2020_03\\demo\\test_yoyo.py:9: AssumptionFailure
E           >>	pytest.assume(x == y)
E           AssertionError: assert False
E           
E           ..\\..\\..\\..\\..\\soft\\code\\pytest_api_2020_03\\demo\\test_yoyo.py:10: AssumptionFailure
E           >>	pytest.assume(x+y > 1)
E           AssertionError: assert False
E           
E           ..\\..\\..\\..\\..\\soft\\code\\pytest_api_2020_03\\demo\\test_yoyo.py:11: AssumptionFailure
E           >>	pytest.assume(x > 1)
E           AssertionError: assert False

E:\\python36\\lib\\site-packages\\six.py:685: FailedAssumption
___________________________ test_simple_assume[0-1] ___________________________

tp = <class 'pytest_assume.plugin.FailedAssumption'>
value = FailedAssumption('\\n3 Failed Assumptions:\\demo\\\\test_yoyo.py:11:
 AssumptionFailure\\n>>\\tpytest.assume(x > 1)\\nAssertionError: assert False\\n\\n',)
tb = <traceback object at 0x00000216CA74D2C8>

    def reraise(tp, value, tb=None):
        if value is None:
            value = tp()
        if value.__traceback__ is not tb:
>           raise value.with_traceback(tb)
E           pytest_assume.plugin.FailedAssumption: 
E           3 Failed Assumptions:
E           
E           ..\\..\\..\\..\\..\\soft\\code\\pytest_api_2020_03\\demo\\test_yoyo.py:9: AssumptionFailure
E           >>	pytest.assume(x == y)
E           AssertionError: assert False
E           
E           ..\\..\\..\\..\\..\\soft\\code\\pytest_api_2020_03\\demo\\test_yoyo.py:10: AssumptionFailure
E           >>	pytest.assume(x+y > 1)
E           AssertionError: assert False
E           
E           ..\\..\\..\\..\\..\\soft\\code\\pytest_api_2020_03\\demo\\test_yoyo.py:11: AssumptionFailure
E           >>	pytest.assume(x > 1)
E           AssertionError: assert False

E:\\python36\\lib\\site-packages\\six.py:685: FailedAssumption
========================== 3 failed in 0.44 seconds ===========================

从运行结果可以看出,三个断言都会执行

上下文管理器

pytest.assume 也可以使用上下文管理器去断言

import pytest
from pytest import assume
# 上海-悠悠

@pytest.mark.parametrize(('x', 'y'),
                         [(1, 1), (1, 0), (0, 1)])
def test_simple_assume(x, y):
    print("测试数据x=%s, y=%s" % (x, y))
    with assume: assert x == y
    with assume: assert x+y > 1
    with assume: assert x > 1
    print("测试完成!")

这样看起来会更优雅一点,对之前写的代码改起来也方便一些

需要注意的是每个with块只能有一个断言,如果一个with下有多个断言,当第一个断言失败的时候,后面的断言就不会起作用的.

import pytest
from pytest import assume
# 以下这种是错误的示例,不要一个with下写多个断言
# 上海-悠悠


@pytest.mark.parametrize(('x', 'y'),
                         [(1, 1), (1, 0), (0, 1)])
def test_simple_assume(x, y):
    print("测试数据x=%s, y=%s" % (x, y))
    with assume:
        assert x == y
        assert x+y > 1
        assert x > 1
    print("测试完成!")

以上是关于pytest文档36-断言失败后还能继续执行pytest-assume的主要内容,如果未能解决你的问题,请参考以下文章

17-pytest-pytest-assume多重校验

pytest 如何在第一项断言失败后不退出 for 循环

Go语言在循环中panic后还能继续执行for循环?

用dlopen和dlsym得到的符号 在dlclose后还能继续使用么

Pytest编写测试函数

《叶问》37期,三节点的MGR集群关掉两个节点后还能继续读写吗