1. 程式人生 > >unittest (python標準庫-開發工具-單元測試框架)

unittest (python標準庫-開發工具-單元測試框架)

字符串 text sel 行程 添加 ise 最簡 window ror

unittest官方文檔摘錄 翻譯 reffer to: https://docs.python.org/3/library/unittest.html#unittest.TextTestRunner

第一部分-使用

1、基本概念

1.1)unittest單元測試框架最初的靈感來自於JUnit,其特點有

  • 支持測試自動化
  • 為測試共享setup和shutdown代碼
  • 可以把單個測試集合成測試用例集
  • 將測試報告框架和測試用例獨立開來

1.2)unittest支持的面向對象的重要理念

  • test fixture
    測試固件:表示一個或多個測試用例需要的準備,以及關聯的清理操作,例如:創建臨時DB、目錄或啟動一個進程

  • test case
    測試用例: 一個獨立的測試單元,它校驗一組輸入得到的一個指定的響應,unittest提供一個基類TestCase,用來創建新的測試用例

  • test suite
    測試套件: 一個測試用例的集合,用來集合應該被一起執行的測試用例

  • test runner
    測試執行組件: 安排測試的執行並給用戶提供結果

2、簡單實例

unittest庫提供了一系列豐富的工具來構建和執行測試,下面講一下可以滿足大部分用戶需求的一個小的工具子集

import unittest

class TestStringMethods(unittest.TestCase):

    def test_upper(self):
        self.assertEqual('foo'.upper(), 'FOO')
    
    def test_isupper(self):
        self.assertTrue('FOO'.isupper())
        self.assertFalse('Foo'.isupper())
    
    def test_split(self):
        s = 'hello world'
        self.assertEqual(s.split(), ['hello', 'world'])
        # check that s.split fails when the separator is not a string
        with self.assertRaises(TypeError):
        s.split(2)

if __name__ == '__main__':
    unittest.main()
  • 測試用例繼承TestCase類,單個測試方法需要已test開頭,這樣便於告訴test runner哪些方法代表測試用例
  • 每一個測試均用到了斷言行數assert*(),以便於test runner計算測試結果及生成測試報告
  • setUp()和tearDown()方法用於定義一些測試前後的操作
  • unittest.main()為測試腳本提供了一個命令行接口來運行測試

3、命令行執行測試的方式

# 您可以像這樣執行一個測試模塊:
python -m unittest test_module1 test_module2
# 也可以執行一個測試類,如:
python -m unittest test_module.TestClass
# 或者單獨執行一個測試方法
python -m unittest test_module.TestClass.test_method

4、組織測試代碼

  • 測試用例: 單元測試的基礎組成模塊是 測試用例--必須建立起來並且完成正確性校驗的單個場景
  • 編寫用例的規範
    • 在unittest框架中,測試用例就是TestCase的實例,所以你必須繼承TestCase類來寫用例
    • 測試方法必須帶self參數,用來單獨運行或則組合運行用例
    • assert*()方法是TestCase類提供的,如果測試失敗了,它會拋出解釋性的說明,unittest則會把這個用例定義為失敗,其他的異常都會被視為錯誤。
    • setUp()方法會在每一個test_func執行之前執行,同理的tearDown
    • 測試用例的執行順序是測試方法名的字符串排序

自由組裝測試套件

import unittest

class WidgetTestCase(unittest.TestCase):
    def setUp(self):
    self.widget = Widget('The widget')

    def tearDown(self):
    self.widget.dispose()

def suite():
    suite = unittest.TestSuite()
    suite.addTest(WidgetTestCase('test_default_widget_size'))
    suite.addTest(WidgetTestCase('test_widget_resize'))
    return suite

if __name__ == '__main__':
    runner = unittest.TextTestRunner()
    runner.run(suite())

5、跳過用例

5.1 跳過一個用例使用skip()裝飾器就可以了,下面是幾個實例

class MyTestCase(unittest.TestCase):

@unittest.skip("demonstrating skipping")
def test_nothing(self):
    self.fail("shouldn't happen")

@unittest.skipIf(mylib.__version__ < (1, 3),
                 "not supported in this library version")
def test_format(self):
    # Tests that work for only a certain version of the library.
    pass

@unittest.skipUnless(sys.platform.startswith("win"), "requires Windows")
def test_windows_support(self):
    # windows specific testing code
    pass  

第二部分-深入unittest APIs

1、Test cases 測試用例相關

unittest.TestCase(methodName="runTest")

  • TestCase類的實例展示了unittest宇宙中單元測試邏輯,這個類被設計為基類,由它的子類來實現特定的測試。
  • 這些子類實現test runner需要的接口,來讓它控制測試用例和各個失敗的檢查和報告的測試方法
  • TestCase實例提供三類方法:
    • A: 用來運行測試: setUp() 、tearDown()、setUpClass()、tearDownClass()、run(result=None)、skipTest(reason)
    • B: 用來實現條件檢查和報告失敗assert*()
    • C: 一些查詢信息的方法

2、Grouping tests 組織測試用例

unittest.TestSuite(tests=())

這個類代表一些單獨測試用例或測試集的集合,TestSuite的對象有點像TestCase對象,除了它並不真正實現一個測試外,另外,它們用來集成需要一起運行的測試,下面是一些常用方法:

  • addTest(test) 向測試集中加入一個測試用例或測試集
  • addTests(tests) 添加多個test
  • run(result)運行suite關聯的測試,收集測試結果放到result中
  • countTestCases()

3、Loading and running tests 加載並執行測試

class unittest.TestLoader

  • 用來通過測試類和或者測試模塊創建測試集,這個類一般無需實例化,
  • 方法:
    • loadTestsFromTestCase(testCaseClass)
    • loadTestsFromModule(module, pattern=None)
    • loadTestsFromName(name, module=None)
    • loadTestsFromNames(names, module=None)
    • getTestCaseNames(testCaseClass)
    • discover(start_dir, pattern=‘test*.py‘, top_level_dir=None)

class unittest.TestResult

  • TestResult對象保存了測試集的測試結果
  • TestRunner.run()會返回一個TestResult實例,用於生成測試不報告用
    • 結果屬性:errors、failures、skipped、testsRun

class unittest.TextTestResult(stream, descriptions, verbosity)

  • 用TextTestRunner對TestResult的實現
  • 方法:
    • _makeResult():通過運行run函數返回一個TestResult實例。
    • run(test): TextTestRunner的主入口,以TestSuite或TestCase為參數,並輸出一個TestResult
    • unittest.main(*):一個從module中載入測試集並執行他們的命令行程序,為了方便測試模塊執行。最簡單的執行方式是:

--

# 執行一個module中的所有用例 
if __name__ == '__main__':
    unittest.main()

4、 Class and Module Fixtures

  • class及module級別的固件(Fixture)在測試套件TestSuite中已經實現, 當suite遇到一個新類中的測試用例時,前一個類先tearDown且新的類會setUp固件。Shared fixtures

unittest (python標準庫-開發工具-單元測試框架)