『德不孤』Pytest框架 — 8、Pytest斷言
- 2022 年 2 月 27 日
- 筆記
- 測試基礎技能 - Pytest測試框架
1、什麼是斷言
對於測試來講,不管是功能測試,自動化測試,還是單元測試,一般都會預設一個正確的預期結果,而在測試執行的過程中會得到一個實際的結果。
測試的成功與否就是拿實際的結果與預期的結果進行比較,這個比的過程就是斷言(assert)。
2、Pytest斷言
- 與Unittest不同,Pytest使用的是Python自帶的
assert
關鍵字來進行斷言。 assert
關鍵字後面可以接一個表達式,只要表達式的最終結果為True,那麼斷言通過,用例執行則為成功,否則用例執行失敗。
3、Pytest的斷言方式及應用場景
(1)使用assert語句
Pytest裏面的斷言實際上就是Python裏面的assert
斷言方法。
1)比較大小與是否相等:
assert a == b
:判斷a等於bassert a !=b
:判斷a不等於b
2)判斷包含或不包含:
assert a in b
:判斷b包含aassert a not in b
:判斷b不包含a
提示:b可以是字符串,可以是列表,元組等都可以。
3)對類型的判斷:
assert isinstance(a,int)
:判斷a是否是int類型數據。
4)判斷方法或者函數的返回值是否為真:
assert xx
:判斷xx結果為真。assert not xx
:判斷xx結果不為真。
例如:
#用於判斷素數
def is_prime(n):
if n <= 1:
return False
for i in range(2, n):
if n % i == 0:
return False
return True
# 判斷是否為素數
def test_true():
assert is_prime(13)
# 或者不為素數
assert not is_prime(13)
基本上常用的就這麼幾種。
(2)斷言預期的異常
將異常信息存儲到一個變量中,變量的類型則為異常類,包含異常的type
、value
和traceback
等信息
import pytest
def test_exception_value():
with pytest.raises(ZeroDivisionError) as zero:
1 / 0 # 此處可以是方法,也可以是表達式
# print(zero) <ExceptionInfo ZeroDivisionError('division by zero') tblen=1>
# print(zero.tb)# <traceback object at 0x0000021B6068BD48>
# print(zero.typename) # 字符串"ZeroDivisionError"
# print(zero.type) # 異常類型<class 'ZeroDivisionError'>
print(zero.traceback)
assert "division by zero" in str(zero.value)
assert zero.type == ZeroDivisionError
assert zero.typename == "ZeroDivisionError"
if __name__ == '__main__':
pytest.main()
注意:在上下文管理器的作用域中,raises代碼必須是最後一行,否則其後面的代碼將不會執行。
(3)拓展
如果我們不知道預期異常的是什麼,我們可以使用 match 和 raise 進行自定義異常。
給pytest.raises()
函數傳遞一個關鍵字參數match
,通過match
設置的字符串正則表達式匹配異常信息。
和Unittest
中的TestCase.assertRaisesRegexp
方法類似。
示例:
import pytest
# myfunc函數會拋出一個異常,
def myfunc():
raise ValueError("Exception 123 raised")
def test_match():
# pytest.raises()函數,
# 可以用元組的形式傳遞參數,只需要觸發其中任意一個即可。
# 通過match可以設置通過正則表達式匹配異常。
with pytest.raises((ValueError, RuntimeError), match=r'.* 123 .*') as ve:
myfunc()
# 說明:myfunc()拋出的異常被match設置的字符串匹配到
# 也就是捕獲到了該異常。
# 然後下面是斷言,123是否包含在捕獲異常的說明中。
assert "123" in str(ve.value)
if __name__ == '__main__':
pytest.main()
4、優化斷言
我們可以在異常的時候,輸出一些提示信息,這樣報錯後,可以方便我們來查看原因。
示例如下:
import pytest
def func():
return 100
def test_case_666():
a = func()
assert a % 3 == 0, "判斷a是否能被3整除,當前a的值為:%s" %a
if __name__ == '__main__':
pytest.main()
"""
運行結果:
========沒加註釋的測試結果==========
Expected :0
Actual :1
<Click to see difference>
def test_case_666():
a = 100
> assert a % 3 == 0
E assert 1 == 0
test_01.py:55: AssertionError
Assertion failed
========添加註釋的測試結果==========
Expected :0
Actual :1
<Click to see difference>
def test_case_666():
a = 100
> assert a % 3 == 0, "判斷a是否能被3整除,當前a的值為:%s" %a
E AssertionError: 判斷a是否能被3整除,當前a的值為:100
E assert 1 == 0
test_01.py:53: AssertionError
Assertion failed
"""
5、使用標記檢查異常
使用注釋:@pytest.mark.xfail(raises=ZeroDivisionError)
示例:
import pytest
@pytest.mark.xfail(raises=ZeroDivisionError)
def test_exception_value():
1 / 0
if __name__ == '__main__':
pytest.main()
# 說明代碼:
# 預期拋出ZeroDivisionError異常,
# 實際測試用例執行也拋出了ZeroDivisionError異常。
# 測試結果:該用例是xfailed