Python為開發者提供了內置的單元測試框架 unittest,它是一種強大的工具,能夠有效地編寫和執行單元測試。unittest 提供了完整的測試結構,支持自動化測試的執行,能夠對測試用例進行組織,并且提供了豐富的斷言方法。最終,unittest 會生成詳細的測試報告,這個框架非常簡單且易于使用。
在 unittest 中,有幾個核心概念:
以下是一個簡單的例子:
import unittestdef login(username, password): if username == 'kira' and password == '123': res = {"code": 200, "msg": "登錄成功"} return res return {"code": 400, "msg": "登錄失敗"}class TestLogin(unittest.TestCase): def test_login_success(self): """測試登錄成功""" test_data = {"username": "kira", "password": "test"} expect_data = {"code": 200, "msg": "登錄成功"} res = login(**test_data) self.assertEqual(res, expect_data) def test_login_error_with_error_password(self): """賬號正確,密碼錯誤,登錄失敗""" test_data = {"username": "kira", "password": "12345"} expect_data = {"code": 400, "msg": "登錄失敗"} res = login(**test_data) self.assertEqual(res, expect_data) # 更多測試函數類似...if __name__ == '__main__': unittest.main()
以上是一個簡單的測試用例,包含了兩個測試函數。運行腳本將輸出測試結果。
測試腳手架 是測試用例的前置條件和后置條件,確保測試環境的初始化和清理,從而保證測試的準確性和可靠性。
import unittestclass MyTestCase(unittest.TestCase): @classmethod def setUpClass(cls): # 類級別的前置條件設置,整個類運行最先只執行一次 print("setUpClass") @classmethod def tearDownClass(cls): # 類級別的后置條件清理,整個類運行最后結束執行一次 print("tearDownClass") def setUp(self): # 測試方法級別的前置條件設置,所有測試方法運行前都執行一次 print("setUp") def tearDown(self): # 測試方法級別的后置條件清理,所有測試方法運行結束都執行一次 print("tearDown") def test_example(self): # 測試用例 print("test_example")if __name__ == "__main__": unittest.main()
測試用例 是最小的測試單元,用于檢測特定的輸入集合的特定的返回值。unittest 提供了 TestCase 基類,所有的測試類都需要繼承該基類,而在該類下的函數如果以 test_ 開頭,則被標識為測試函數:
class MyTestCase(unittest.TestCase): def test_addition(self): result = 2 + 3 self.assertEqual(result, 5) # 使用斷言方法驗證結果是否相等 def test_subtraction(self): result = 5 - 3 self.assertTrue(result == 2) # 使用斷言方法驗證結果是否為True # 更多測試用例函數...
以下是常用的斷言方法:
可以使用這些方法進行斷言,也可以直接使用原生的assert來斷言,如果斷言失敗,測試用例會被定義為執行失敗。
unittest 提供了一些方法來跳過特定的測試用例:
使用實例方法:self.skipTest() 使用和上述類似。
import sysimport unittestclass Test1(unittest.TestCase): @unittest.expectedFailure # 即使失敗也會被計為成功的用例 def test_1(self): assert 1 + 1 == 3 @unittest.skip('無條件跳過') # 不管什么情況都會進行跳過 def test_2(self): print("2+2...", 4) @unittest.skipIf(sys.platform == "win32", "跳過") # 如果系統平臺為 Windows 則跳過 def test_3(self): print("3+3...", 6) @unittest.skipUnless(sys.platform == "win32", "跳過") # 除非系統平臺為 Windows,否則跳過 def test_4(self): print("4+4...", 8) def test_5(self): self.skipTest("跳過") print("5+5...", 10)if __name__ == "__main__": unittest.main(verbosity=2)
測試套件用于收集和組織多個測試用例,便于集中執行。
此方式適用于需要自定義組合特定測試用例的情況。
import unittestclass MyTestCase(unittest.TestCase): def test_addition(self): result = 2 + 3 self.assertEqual(result, 5)def suite(): suite = unittest.TestSuite() suite.addTest(MyTestCase('test_addition')) return suiteif __name__ == '__main__': runner = unittest.TextTestRunner() runner.run(suite())
TestLoader 是 unittest 框架提供的加載測試用例的類。
import unittestif __name__ == '__main__': loader = unittest.defaultTestLoader # 自動加載當前模塊中所有以 'test_' 開頭的測試用例函數 suite = loader.loadTestsFromModule(__name__) runner = unittest.TextTestRunner() runner.run(suite)
import unittestclass MyTestCase(unittest.TestCase): def test_addition(self): result = 2 + 3 self.assertEqual(result, 5)if __name__ == '__main__': loader = unittest.defaultTestLoader # 自動加載 MyTestCase 類中的所有測試用例 suite = loader.loadTestsFromTestCase(MyTestCase) runner = unittest.TextTestRunner() runner.run(suite)
import unittestif __name__ == '__main__': loader = unittest.defaultTestLoader # 自動加載指定名稱的測試用例 suite = loader.loadTestsFromName('module.MyTestCase.test_addition') runner = unittest.TextTestRunner() runner.run(suite)
import unittestif __name__ == '__main__': loader = unittest.defaultTestLoader # 自動發現并加載指定目錄中的測試用例模塊 suite = loader.discover(start_dir='test_directory', pattern='test_*.py', top_level_dir=None) runner = unittest.TextTestRunner() runner.run(suite)
測試運行器是用于執行和輸出測試結果的組件。常用的運行器有:
import unittestif __name__ == '__main__': loader = unittest.defaultTestLoader suite = loader.discover(start_dir='tests', pattern='test_*.py') runner = unittest.TextTestRunner() result = runner.run(suite)
import unittestfrom HTMLTestRunner import HTMLTestRunnerif __name__ == '__main__': loader = unittest.defaultTestLoader suite = loader.discover(start_dir='tests', pattern='test_*.py') with open('test_report.html', 'wb') as report_file: runner = HTMLTestRunner(stream=report_file, title='Test Report', description='Test Results') result = runner.run(suite)
import unittestfrom xmlrunner import XMLTestRunnerif __name__ == '__main__': loader = unittest.defaultTestLoader suite = loader.discover(start_dir='tests', pattern='test_*.py') with open('test_report.xml', 'wb') as report_file: runner = XMLTestRunner(output=report_file) result = runner.run(suite)
你也可以自定義測試運行器。繼承 unittest.TestRunner 類并實現 run() 方法,以創建自己的測試運行器。
import unittestclass MyTestRunner(unittest.TextTestRunner): def run(self, test): print("Running tests with MyTestRunner") result = super().run(test) return resultif __name__ == '__main__': loader = unittest.defaultTestLoader suite = loader.discover(start_dir='tests', pattern='test_*.py') runner = MyTestRunner() result = runner.run(suite)
通常使用 HTMLTestRunner 即可滿足需求,它非常易用。
假設有一個測試函數 login:
# login.pydef login(username, password): """模擬登錄校驗""" if username == 'kira' and password == '123456': return {"code": 0, "msg": "登錄成功"} else: return {"code": 1, "msg": "賬號或密碼不正確"}
根據函數的參數和邏輯,設計如下用例:
import unittestfrom login import loginclass TestLogin(unittest.TestCase): def test_login_correct(self): """測試賬號密碼正確""" test_data = {"username": "kira", "password": "123456"} expect_data = {"code": 0, "msg": "登錄成功"} res = login(**test_data) self.assertEqual(res, expect_data) def test_login_wrong_password(self): """測試賬號正確密碼不正確""" test_data = {"username": "kira", "password": "123"} expect_data = {"code": 1, "msg": "賬號或密碼不正確"} res = login(**test_data) self.assertEqual(res, expect_data) def test_login_wrong_username(self): """測試賬號錯誤密碼正確""" test_data = {"username": "kir", "password": "123456"} expect_data = {"code": 1, "msg": "賬號或密碼不正確"} res = login(**test_data) self.assertEqual(res, expect_data)if __name__ == '__main__': unittest.main()
這是一個簡單的測試用例,包含了三個測試函數。運行測試用例后,會輸出測試結果,看完是否覺得unittest非常簡單易用。ner.run(suite)
本文鏈接:http://www.tebozhan.com/showinfo-26-10432-0.html不拼花哨,只拼實用:Unittest指南,干貨為王!
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com
上一篇: 基于范圍的 for 循環:現代 C++ 循環控制的新思維
下一篇: 2023年需求最大的八種編程語言