前言
pytest的斷言失敗后,后面的代碼就不會執行了,通常一個用例我們會寫多個斷言,有時候我們希望第一個斷言失敗后,后面能繼續斷言。
pytest-assume插件可以解決斷言失敗后繼續斷言的問題。github地址:https://github.com/astraw38/pytest-assume
環境准備
先安裝pytest-assume依賴包
pip install pytest-assume
遇到問題
一下是一個簡單案例,輸入的測試數據有3種,我們需要斷言同時滿足三種情況
x==y , x+y>1 ,x>0
import pytest @pytest.mark.parametrize(('x','y'),[(1,1),(1,0),(0,1)]) def test_simple(x,y): print("測試數據x:{},y:{}".format(x,y)) assert x==y assert x+y>1 assert x>0
運行結果
================================== FAILURES =================================== ______________________________ test_simple[1-0] _______________________________ x = 1, y = 0 @pytest.mark.parametrize(('x','y'),[(1,1),(1,0),(0,1)]) def test_simple(x,y): print("測試數據x:{},y:{}".format(x,y)) > assert x==y E assert 1 == 0 test_a.py:6: AssertionError ---------------------------- Captured stdout call ----------------------------- 測試數據x:1,y:0 ______________________________ test_simple[0-1] _______________________________ x = 0, y = 1 @pytest.mark.parametrize(('x','y'),[(1,1),(1,0),(0,1)]) def test_simple(x,y): print("測試數據x:{},y:{}".format(x,y)) > assert x==y E assert 0 == 1 test_a.py:6: AssertionError ---------------------------- Captured stdout call ----------------------------- 測試數據x:0,y:1 =========================== short test summary info =========================== FAILED test_a.py::test_simple[1-0] - assert 1 == 0 FAILED test_a.py::test_simple[0-1] - assert 0 == 1 ========================= 2 failed, 1 passed in 0.16s =========================
如果第一個斷言就失敗了,后面的2個斷言都不會執行了。
pytest-assume使用案例
使用pytest.assume斷言
#test_a.py import pytest @pytest.mark.parametrize(('x','y'),[(1,1),(1,0),(0,1)]) def test_simple(x,y): print("測試數據x:{},y:{}".format(x,y)) pytest.assume(x==y) pytest.assume(x+y>1) pytest.assume(x>0) print("測試完成!")
運行結果
================================== FAILURES =================================== ______________________________ test_simple[1-0] _______________________________ 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_a.py:6: AssumptionFailure E >> pytest.assume(x==y) E AssertionError: assert False E E test_a.py:7: AssumptionFailure E >> pytest.assume(x+y>1) E AssertionError: assert False C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\site-packages\six.py:695: FailedAssumption ---------------------------- Captured stdout call ----------------------------- 測試數據x:1,y:0 測試完成! ______________________________ test_simple[0-1] _______________________________ 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 3 Failed Assumptions: E E test_a.py:6: AssumptionFailure E >> pytest.assume(x==y) E AssertionError: assert False E E test_a.py:7: AssumptionFailure E >> pytest.assume(x+y>1) E AssertionError: assert False E E test_a.py:8: AssumptionFailure E >> pytest.assume(x>0) E AssertionError: assert False C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\site-packages\six.py:695: FailedAssumption ---------------------------- Captured stdout call ----------------------------- 測試數據x:0,y:1 測試完成! =========================== short test summary info =========================== FAILED test_a.py::test_simple[1-0] - pytest_assume.plugin.FailedAssumption: FAILED test_a.py::test_simple[0-1] - pytest_assume.plugin.FailedAssumption: ========================= 2 failed, 1 passed in 0.25s =========================
從運行結果可以看出,三個斷言都會執行。
上下文管理器
pytest.assume也可以使用上下文管理器去斷言
#test_a.py import pytest from pytest import assume @pytest.mark.parametrize(('x','y'),[(1,1),(1,0),(0,1)]) def test_simple(x,y): print("測試數據x:{},y:{}".format(x,y)) with assume:assert x==y with assume:assert x+y>1 with assume:assert x>0 print("測試完成")
這樣看起來會更優雅一點,對之前寫的代碼改起來也方便一些
需要注意的是每個with塊只能有一個斷言,如果一個with下有多個斷言,當第一個斷言失敗的時候,后面的斷言就不會起作用的。
#test_a.py import pytest from pytest import assume @pytest.mark.parametrize(('x','y'),[(1,1),(1,0),(0,1)]) def test_simple(x,y): print("測試數據x:{},y:{}".format(x,y)) with assume: assert x==y assert x+y>1 assert x>0 print("測試完成")