前言
pytest作為單元測試框架,自然少不了斷言功能,用過unittest的人都知道,在unittest中有豐富的斷言方法,比如assertEqual()、assertIn()、assertTrue()、assertIs()等等,而在pytest中,並沒有提供特殊的斷言方法,而是直接使用python自帶的關鍵字assert來進行斷言操作。
下面我們就通過一些?來看看在pytest中是如何進行斷言操作的吧
常用斷言
Pytest
裡的斷言實際上就是Python中的assert斷言方法,常用斷言方法如下:
- assert xx :判斷 xx 為真
- assert not xx :判斷 xx 不為真
- assert a in b :判斷 b 包含 a
- assert a == b :判斷 a 等於 b
- assert a != b :判斷 a 不等於 b
舉個?:
import pytest
def test_demo1():
a = 1
assert a
def test_demo2():
a = 0
assert not a
def test_demo3():
s = 'hello'
assert 'h' in s
def test_demo4():
a = 3
assert a == 3
def test_demo5():
a = 4
assert a != 3
if __name__ == '__main__':
pytest.main()
執行結果如下:
如果想在異常的時候,能夠輸出一些提示資訊,可在直接在斷言後面加上提示資訊,如下:
import pytest
def test_demo6():
a = 5
assert a == 3, "兩者不相等"
執行結果:
異常斷言
在實際測試的過程中,我們經常需要對特定異常進行斷言,可以使用 pytest.raises 作為上下文管理器,當丟擲異常時可以獲取到對應的異常例項
舉個?:
import pytest
def test_zero_division():
1 / 0
if __name__ == '__main__':
pytest.main()
執行結果:
可以看到,這裡程式異常了,所以我們需要捕獲並斷言異常。
斷言場景:斷言丟擲的異常是否符合預期。
預期結果:ZeroDivisionError: division by zero,其中ZeroDivisionError為錯誤型別,division by zero為具體錯誤值。
斷言方式: 斷言異常的type和value值。
斷言程式碼如下:
import pytest
def test_zero_division():
with pytest.raises(ZeroDivisionError) as excinfo:
1 / 0
# 斷言異常型別 type
assert excinfo.type == ZeroDivisionError
# 斷言異常 value 值
assert "division by zero" in str(excinfo.value)
if __name__ == '__main__':
pytest.main()
excinfo作為異常資訊例項,擁有type 、value、.traceback等屬性
excinfo.value的值是元組,所以要轉成字串
在上下文管理器的作用域中,raises程式碼必須是最後一行,否則,其後面的程式碼將不會執行
擴充:match
你也可以給pytest.raises()
傳遞一個關鍵字引數match
,來測試異常的字串表示str(excinfo.value)
是否符合給定的正規表示式(和unittest
中的TestCase.assertRaisesRegexp
方法類似):
import pytest
def func():
raise ValueError("Exception 123 raised")
def test_match():
# pytest.raises()函式,
# 可以用元組的形式傳遞引數,只需要觸發其中任意一個即可。
# 通過match可以設定通過正規表示式匹配異常。
with pytest.raises((ValueError, RuntimeError), match=r'.* 123 .*') as excinfo:
func()
assert “123” in str(excinfo.value)
if __name__ == '__main__':
pytest.main()
擴充:檢查斷言裝飾器
pytest.mark.xfail()
也可以接收一個raises
引數,來判斷用例是否因為一個具體的異常而導致失敗:
@pytest.mark.xfail(raises=ZeroDivisionError)
def test_f():
1 / 0
執行結果:
如果
test_f()
觸發的異常型別和raises指定的異常型別一致,則用例被標記為xfailed
如果
test_f()
測試成功,用例的結果是xpassed
,而不是passed
pytest.raises
適用於檢查由程式碼故意引發的異常;而@pytest.mark.xfail()
更適合用於記錄一些未修復的 Bug