pytest--assert斷言 unittest_斷言
前言
在自動化測試中,判斷一個測試用例是否執行通過,通常使用assert去判斷實際輸出結果與預期結果是否一致。與unittest提供自己的斷言方法(unittest_斷言
)不同,在pytest中直接對python的assert關鍵字進行重寫,能夠輸出更多的錯誤資訊,來幫助定位出問題的測試用例以及程式碼行
pytest斷言
那麼直接寫一個簡單的斷言測試用例,來看下會比平常python斷言多輸出哪些資訊
demo_assert.py:
import pytest class Test_01: def add(self,x,y): c = x+y returnc def test_01(self): a =2 b =3 c = self.add(a,b) assert c == 4
if __name__ == '__main__':
pytest.main()
在cmd中執行pytest test_assert.py,輸出結果如下:
>這行列印的是python斷言資訊輸出,E這行列印的則是pytest新增的斷言資訊輸出,可以看到pytest直接將c的數值打印出來,很直觀的可以看到數值上5不等於4,錯誤型別為AssertionError
當然如果你覺得輸出的斷言資訊不夠通俗易懂。那麼pytest也保留了python斷言的自定義斷言輸出,可以轉換為通俗易懂的斷言資訊,或將一些引數資訊列印輸出。只需要再assert後面新增列印資訊,用,進行分隔,程式碼如下:
import pytest class Test_01: def add(self,x,y): c = x+y return c def test_01(self): a =2 b =3 c = self.add(a,b) assert c == 4 ,f"a的值:{a}+b的值:{b},經過add計算得到{c},其結果不等於4" if __name__ == '__main__': pytest.main()
輸出結果如下:
可以看到E多了一行,輸出內容為錯誤型別:自定義斷言輸出,如:AssertionError: a的值:2+b的值:3,經過add計算得到5,其結果不等於4
可以看到輸出的斷言資訊更加通俗易懂,將相關引數的數值都打印出來,方便後期測試用例的錯誤定位和維護
常用斷言
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
異常斷言
當你執行一條錯誤用例時,已經知道它的錯誤型別時,可以通過pytest.raises(錯誤型別)作為上下文管理器來判斷,如果執行丟擲的錯誤型別與所確認的錯誤用例,那麼這條測試用例就會判斷通過,反之報錯,打印出錯誤資訊。
上面用例可以看到丟擲的錯誤型別為AssertionError,那麼就可以with pytest,raise(AssertionError)來判斷
import pytest class Test_01: def add(self,x,y): c = x+y return c def test_01(self): a =2 b =3 with pytest.raises(AssertionError): c = self.add(a,b) assert c == 4 ,f"a的值:{a}+b的值:{b},經過add計算得到{c},其結果不等於4" if __name__ == '__main__': pytest.main()
重新執行,輸出結果如下:
可以看到該用例丟擲的錯誤型別確實是AssertionError,所以該用例測試通過
上面的異常斷言,可以進行例項化,例項化過後存在三個可以用的方法,分別是.type,.value,.traceback
- type:錯誤型別
- value:錯誤的數值
- traceback:錯誤的測試用例以及程式碼行數
import pytest class Test_01: def add(self,x,y): c = x+y return c def test_01(self): a =2 b =3 with pytest.raises(AssertionError) as excinfo: c = self.add(a,b) assert c == 4 ,f"a的值:{a}+b的值:{b},經過add計算得到{c},其結果不等於4" print(f'錯誤的數值:{excinfo.value}') print(f'錯誤型別:{excinfo.type}') print(f'錯誤行數:{excinfo.traceback}') if __name__ == '__main__': pytest.main()
執行pytest test_assert.py -s,將其詳細資訊打印出來,執行結果如下
補充:
1、match引數
pytest.raises可以傳入match引數,已測試正則表示式與異常的字串表示形式是否匹配,這種方法只能斷言value,不能斷言type
例如,match傳入正則表示式 .*其結果*. 如果value中包含這3個字,那麼這個用例也可以通過,反之哪怕錯誤型別對應了,這個用例也會報錯
import pytest class Test_01: def add(self,x,y): c = x+y return c def test_01(self): a =2 b =3 with pytest.raises(AssertionError,match='.*其結果*.') as excinfo: c = self.add(a,b) assert c == 4 ,f"a的值:{a}+b的值:{b},經過add計算得到{c},其結果不等於4" print(f'錯誤的數值:{excinfo.value}') print(f'錯誤型別:{excinfo.type}') print(f'錯誤行數:{excinfo.traceback}') if __name__ == '__main__': pytest.main()
當然,如果不使用正則表示式,match直接傳入一個值,例如
with pytest.raises(AssertionError,match='其結果') as excinfo:
這樣表示value只要包含“其結果”,用例也是可以通過的
2、@pytest.mark.xfail(raises=錯誤型別)檢查斷言修飾器
除了pytest.raises外,也提供了@pytest.mark.xfail(raises=錯誤型別)修飾器來判斷預期錯誤型別與實際錯誤型別是否一致,程式碼如下:
import pytest class Test_01: def add(self,x,y): c = x+y return c @pytest.mark.xfail(raises=AssertionError) def test_01(self): a =2 b =3 c = self.add(a,b) assert c == 4 ,f"a的值:{a}+b的值:{b},經過add計算得到{c},其結果不等於4" if __name__ == '__main__': pytest.main()
如果結果一致,那麼pytest執行結果會是xfailed的結果,如果不一致,那麼結果是直接fail,輸出如下: