前言
实际编写自动化测试用例时,一个用例中我们通常会写多个断言,当第一个断言失败后,后面的代码就不会执行了,但有时候我们希望第一个断言失败后,后面还可以继续断言,那该如何解决这个需求呢?
pytest-assume 是啥
针对前言中问题,我们使用pytest-assume 插件可以方便解决。
pytest-assume插件可以解决断言失败后继续执行后面断言的问题。
安装 pytest-assume 插件
在命令行中运行以下命令,安装 pytest-assume插件:
pip install pytest-assume
pytest-assume如何使用
方法一:
导入pytest
,使用pytest.assume()
进行断言
方法二:
使用with上下文管理器编写,像这样
python
from pytest_assume.plugin import assume
def test_add():
with assume: assert 1 == 2
使用案例
我们写一些测试用例看一下效果
test_demo.py
python
import pytest
def add(x, y):
return x + y
def test_addition():
result = add(2, 3)
assert result == 2 # 第一个断言
assert result > 0 # 第二个断言
assert result % 2 == 0 # 第三个断言
未使用插件前,应该在第一个断言失败就会停下来,但第二个断言是通过的,由于第一个断言失败导致停止运行。
先看看不用该插件的执行效果:
markdown
...
____________________________________________________________ test_addition _____________________________________________________________
def test_addition():
result = add(2, 3)
> assert result == 2 # 第一个断言
E assert 5 == 2
test_dir/test_demo.py:8: AssertionError
可以看到用例执行到第一个断言失败,就停止运行了,后面的断言并没有执行。
我们使用方法一:pytest.assume() 对代码进行调整,像这样
scss
import pytest
def add(x, y):
return x + y
def test_addition():
result = add(2, 3)
pytest.assume(result == 2)
pytest.assume(result > 0)
pytest.assume(result % 2 == 0)
再看看使用插件的执行效果:
markdown
...
____________________________________________________________ test_addition _____________________________________________________________
tp = <class 'pytest_assume.plugin.FailedAssumption'>, value = None, tb = None
def reraise(tp, value, tb=None):
try:
if value is None:
value = tp()
if value.__traceback__ is not tb:
> raise value.with_traceback(tb)
E pytest_assume.plugin.FailedAssumption:
E 2 Failed Assumptions:
E
E test_dir/test_demo.py:12: AssumptionFailure
E >> pytest.assume(result == 2)
E AssertionError: assert False
E
E test_dir/test_demo.py:14: AssumptionFailure
E >> pytest.assume(result % 2 == 0)
E AssertionError: assert False
../venv/lib/python3.8/site-packages/six.py:718: FailedAssumption
从结果可以看到,第一个断言失败后,没有停止运行,继续执行直到最后一个断言结束,但会统计错误的次数,像结果中的2 Failed Assumptions
使用方法中还提到了方法二:with上下文管理器,我们使用这种方法来改造一下代码,像这样
python
from pytest_assume.plugin import assume
def add(x, y):
return x + y
def test_addition():
result = add(2, 3)
with assume: assert result == 2
with assume: assert result > 0
with assume: assert result % 2 == 0
执行之后,你会发现结果是一样的,这里就不详细说了。
运行原理
到这里应该知道如何使用了,我们接下来看看它的运行原理:
- 解析测试用例:pytest会解析测试文件中的所有测试用例,并将其标记为测试函数。
- 执行测试函数:pytest按照定义的顺序执行测试函数。当遇到使用pytest.assume断言时,它不会立即抛出异常,而是将当前断言的结果存储在内部的断言缓冲区中。
- 继续执行:即使前面的断言失败,pytest-assume会继续执行后续的断言和代码,而不会中止整个测试用例的执行。
- 收集断言结果:在所有断言执行完毕后,pytest-assume会从断言缓冲区中获取所有断言的结果,并进行汇总。
- 报告结果:最终,pytest会根据断言的结果生成测试报告,包括每个断言的状态(通过或失败),以及整个测试用例的状态(通过或失败)。
通过上述步骤,pytest-assume插件实现了对多个断言的执行和收集结果,而不中断整个测试用例。这样,我们可以一次性看到所有断言的结果,方便查看测试用例的完整执行情况。
需要注意的是,pytest-assume仅影响使用pytest.assume断言的代码块。其他未使用pytest.assume的断言将按照pytest默认的行为执行。因此,在编写测试用例时,需要明确使用pytest.assume来标识希望进行多个断言的代码块。
总结起来,pytest-assume插件的原理是将断言结果存储在缓冲区中,并在所有断言执行完毕后进行结果汇总,从而实现对多个断言的执行和报告。这提供了更灵活和全面的测试方式,方便开发人员对被测试代码进行全面的验证和检查。
结论
使用pytest-assume插件,我们可以更方便地组织和管理测试用例,尤其是当一个测试用例需要多个相关断言时。它为我们提供了更灵活的测试方式,让我们能够更全面地检查被测试代码的行为。