【python】unittest與pytest 模組 _ 測試框架
unittest
官方參考地址:
https://docs.python.org/zh-cn/3/library/unittest.html?highlight=assertequal#module-unittest
1、安裝及匯入
# unittest是python內建的用於測試程式碼的模組,無需安裝直接匯入使用即可
import unittest
2、使用
注意事項:
1、測試檔案必須先匯入模組 import unittest 2、測試類必須繼承 unittest.TestCase 3、測試方法必須由test開頭 4、測試類執行統一用unittest.main()
5、setUpClass和tearDownClass 必須使用@classmethod裝飾器
6、unittest執行測試用例,預設是根據ASCII碼的順序載入測試用例,數字與字母的順序為:0-9,A-Z,a-z。
# coding:utf-8 import unittest #模組匯入 import requests ''' unittest特點: 1、測試檔案必須先匯入模組 import unittest 2、測試類必須繼承 unittest.TestCase 3、測試方法必須由test開頭 4、測試類執行統一用unittest.main() 5、setUpClass和tearDownClass 必須使用@classmethod裝飾器TestDemo''' class TestDemo(unittest.TestCase): @classmethod # 所有test執行前執行一次 def setUpClass(cls): print("setUpClass 開始執行測試方法") @classmethod # 所有test執行完執行一次 def tearDownClass(cls): print("tearDownClass 測試方法全部執行完成") # 設定每個test測試開始前需要執行的指令,準備測試環境 def setUp(self):print("setUp 準備環境") # 設定每個test測試完成後需要執行的指令,清理測試環境 def tearDown(self): print("tearDown 環境復原") # 測試方法 def test_step_one(self): self.assertEqual(6, 6, msg="不通過") def test_step_two(self): # 檢查兩個值的相等性; self.assertEqual([1, 2, 3], [1, 2, 3], "斷言比對不一致") # 斷言1和1是否相等 def test_step_three(self): # 比較測試值與true self.assertTrue(True, msg="失敗原因:比對不一致") # def test_step_four(self): # self.assertEquals([1, 2, 3], [3, 2, 1], msg="比對不一致") if __name__=="__main__": # 提供了一個測試指令碼的命令列介面,用來測試繼承unittest.TestCase的類中以 test 開頭的測試用例 unittest.main()
執行結果
unittest.main(verbosity=0) 簡潔,只能獲得總的測試用例數和總的結果
unittest.main(verbosity=1) 預設,每個成功的用例前面有個“.” ,每個失敗的用例前面有個 “E”
unittest.main(verbosity=2) 詳情,會顯示每個測試用例的所有相關的資訊
3、裝飾器
@ 是修飾符
跳過測試用例 [不會執行被修飾器修飾的方法,類,setup等]
@unittest.skip(reason)
跳過被此裝飾器裝飾的測試。 reason 為測試被跳過的原因。
@unittest.skipIf(condition, reason)
當 condition 為真時,跳過被裝飾的測試。
@unittest.skipUnless(condition, reason)
跳過被裝飾的測試,除非 condition 為真。
@unittest.expectedFailure
將測試標記為預期的失敗或錯誤。 如果測試失敗或在測試函式自身(而非在某個 test fixture 方法)中出現錯誤則將認為是測試成功。 如果測試通過,則將認為是測試失敗。
exception unittest.SkipTest(reason)
引發此異常以跳過一個測試。
示例:
# coding:utf-8 import unittest #模組匯入 import requests ''' unittest特點: 1、測試檔案必須先匯入模組 import unittest 2、測試類必須繼承 unittest.TestCase 3、測試方法必須由test開頭 4、測試類執行統一用unittest.main() 5、setUpClass和tearDownClass 必須使用@classmethod裝飾器 ''' class TestDemo(unittest.TestCase): # 測試方法 @unittest.skip("無條件跳過被此裝飾器裝飾的測試: test_step_one") def test_step_one(self): self.assertEqual(1, 2, "斷言比對不一致") # 斷言1和1是否相等 @unittest.skipIf(True, "當 condition 為真時,跳過被裝飾的測試:test_step_two") def test_step_two(self): # 比較測試值與true self.assertEqual(1, 1, "斷言比對不一致") # 斷言1和1是否相等 @unittest.skipUnless(False, "跳過被裝飾的測試,除非 condition 為真:test_step_three") def test_step_three(self): self.assertEqual(1, 2, "斷言比對不一致") # 斷言1和1是否相等 @unittest.expectedFailure # 預期失敗的情況 def test_step_four(self): # 檢查兩個值的相等性; self.assertEqual(1, 2, "斷言比對不一致") # 斷言1和1是否相等 if __name__=="__main__": # 提供了一個測試指令碼的命令列介面,用來測試繼承unittest.TestCase的類中以 test 開頭的測試用例 unittest.main()TestDemo
執行結果
4、斷言
pytest 安裝及使用
官方參考連結:https://docs.pytest.org/en/7.0.x/
1、安裝及匯入
# pytest 是python第三方單元測試框架,相容unittest
pip install pytest
2、使用
注意事項
1、檔名都需要滿足test_*.py格式或*_test.py格式。 2、測試類以Test開頭,並且不能帶有 init 方法,可以包含一個或多個test_開頭的函式 3、直接執行pytest.main():自動查詢當前目錄下,以test_開頭的檔案或者以_test結尾的py檔案 4、斷言使用assert
1、自動查詢當前目錄下,以test_xxx開頭或者以xxx_test結尾的py檔案 2、main() 可傳入執行引數及外掛引數(通過[]進行分割,多個引數用逗號分割) 3、pytest.main(['目錄名']) # 執行目錄及子目錄下所有用例 4、pytest.main(['test_xx.py‘]) # 執行指定模組所有用例 5、pytest.main(['test_xx.py::TestClass::test_def']) # 指定模組、類、用例(方法) 6、其他引數配置 -m=xxx: 執行打標籤的用例 -reruns=xxx,失敗重新執行 -q: 安靜模式, 不輸出環境資訊 -v: 豐富資訊模式, 輸出更詳細的用例執行資訊 -s: 顯示程式中的print/logging輸出 --resultlog=./log.txt 生成log --junitxml=./log.xml 生成xml報告pytest.main() 引數
pytest執行中會出現6個退出code清單 code 0 全部用例執行通過 code 1 全部用例執行完成,存在失敗用例 code 2 測試執行過程中人為中斷 code 3 測試執行過程發生了內部錯誤 code 4 pytest 命令列使用錯誤 code 5 沒有發現可用的測試用例檔案
執行pytest
# 執行當前目錄下的所有用例 > pytest #==== 2 failed, 4 passed, 3 skipped, 1 xfailed in 0.32s ==== # 執行指定模組 > pytest test_run_case_pytest.py #2 failed, 3 skipped, 1 xfailed in 0.26s # 執行指定模組下的指定用例 > pytest test_run_case_pytest.py::TestPy::test_funski #==== 1 skipped in 0.02s ==== # 模糊匹配包含func用例 > pytest -k func test_run_case_pytest.py #==== 2 failed, 4 deselected in 0.25s ====
3、斷言
Pytest使用的是python自帶的關鍵字assert來斷言【格式:assert 表示式,“預期失敗資訊”】結果為True 用例成功,False 用例失敗
4、修飾器
pytest.skip
# pytest.skip (用於函式內,跳過測試用例) def test_funski(self): for i in range(9): if i > 3: pytest.skip("函式內跳過測試") pass
執行結果:
@pytest.mark.skip # 無條件跳過用例(方法) def test_case1(self): print("\n") assert 2 + 3 == 6, "結果比對不符合要求"
執行結果:
@pytest.mark.skipif(condition="2>0", reason="條件成立 跳過測試") def test_print(self): print("print列印日誌")
執行結果:
@pytest.mark.xfail(True, reason="reason") # 跳過預期失敗用例,當condition =True 且實際失敗則跳過用例 def test_case2(self): assert add(14, 7) == 20, "不滿足預期結果"
執行結果:
# coding:utf-8 import pytest from pawd.base.Logger import * def add(a:int, b:int=0): return a+b class TestPy(): ''' 1、檔名都需要滿足test_*.py格式或*_test.py格式。 2、測試類以Test開頭,並且不能帶有 init 方法,可以包含一個或多個test_開頭的函式 3、直接執行pytest.main():自動查詢當前目錄下,以test_開頭的檔案或者以_test結尾的py檔案 :return: ''' def test_func(self): raise IOError("E") # raise 指定異常的型別 IOError def test_myfunc(self): # 使用pytest去斷言異常的型別 ,異常一致則用例通過,否則用例敗 with pytest.raises(SystemError): self.test_func() def test_logs(self): logs.info("logs列印日誌") def test_print(self): print("print列印日誌") @pytest.mark.skip # 無條件跳過用例 def test_case1(self): print("\n") assert 2 + 3 == 6, "結果比對不符合要求" @pytest.mark.flaky(reruns=5, reruns_delay=2) def test_case2(self): for i in range(9): # assert add(14, i) == 20, "不滿足預期結果" try: assert add(14, i) == 20, "不滿足預期結果" except: continue else: logs.debug(i) if __name__ == "__main__": ''' 1、自動查詢當前目錄下,以test_xxx開頭或者以xxx_test結尾的py檔案 2、main() 可傳入執行引數及外掛引數(通過[]進行分割,多個引數用逗號分割) 3、pytest.main(['目錄名']) # 執行目錄及子目錄下所有用例 4、pytest.main(['test_xx.py‘]) # 執行指定模組所有用例 5、pytest.main(['test_xx.py::TestClass::test_def']) # 指定模組、類、用例(方法) 6、其他引數配置 -m=xxx: 執行打標籤的用例 -reruns=xxx,失敗重新執行 -q: 安靜模式, 不輸出環境資訊 -v: 豐富資訊模式, 輸出更詳細的用例執行資訊 -s: 顯示程式中的print/logging輸出 --resultlog=./log.txt 生成log --junitxml=./log.xml 生成xml報告 ''' pytest.main(['-s'])TestPy類
執行結果:
拓展
單元測試
定義:是指檢查程式碼的實現和邏輯,針對的是模組、函式、類等
核心概念:
test case(測試用例):一個testcase的例項就是一個測試用例。測試前準備環境的搭建(setUp),執行測試程式碼(run),以及測試後環境的還原(tearDown)
TestSuite(測試套件):多個測試用例集合在一起。
TestLoader(測試執行器):用來載入Testcase到TestSuite中。
test fixture(測試環境資料準備和資料清理或者測試腳手架):測試用例環境的搭建和銷燬
TextTestRunner:用來執行測試用例,其中run(test)會執行TestSuite/TestCase中的run(result)方法。
測試目錄結構
Log:日誌記錄和管理功能,針對不同的情況,設定不同的日誌級別,方便定位問題;
Report:測試報告生成和管理以及即時通知,測試結果快速響應;
Source:配置檔案、靜態資源的管理,遵循高內聚低耦合原則;
Common:公共函式、方法以及通用操作的管理,遵循高內聚低耦合原則;
TestCase:測試用例管理功能,一個功能點對應一個或者多個case,儘可能的提高覆蓋率;
TestData:測試資料管理功能,資料與指令碼分離,降低維護成本,提高可移植性;
TestSuite:測試元件管理功能,針對不同場景不同需求,組裝構建不同的測試框架,遵循框架的靈活性和擴充套件性;
Statistics:測試結果統計管理功能,每次執行測試的結果統計、分析、對比以及反饋,資料驅動,為軟體優化和流程改進,提供參考;
Continuous:持續整合環境,即CI環境,包括測試檔案提交、掃描編譯、執行測試、生成報告及時通知等功能,持續整合是自動化測試的核心!