- 單元測試框架教程
- 單元測試框架 - 首頁
- 單元測試框架 - 概述
- 單元測試框架 - 框架
- 單元測試框架 - API
- 單元測試框架 - 斷言
- 單元測試框架 - 測試發現
- 單元測試框架 - 跳過測試
- 單元測試框架 - 異常測試
- 單元測試框架 - 時間測試
- 單元測試框架 - Unittest2
- 單元測試框架 - 訊號處理
- 單元測試框架 - Doctest
- 單元測試框架 - Doctest API
- 單元測試框架 - Py.test 模組
- Nose 測試 - 框架
- Nose 測試 - 工具
- 單元測試框架資源
- 單元測試框架 - 快速指南
- 單元測試框架 - 資源
- 單元測試框架 - 討論
單元測試框架 - API
本章討論 unittest 模組中定義的類和方法。此模組中有五個主要的類。
TestCase 類
此類的物件表示最小的可測試單元。它包含測試例程,並提供用於準備每個例程以及之後清理的鉤子。
TestCase 類中定義了以下方法:
| 序號 | 方法及描述 |
|---|---|
| 1 | setUp() 用於準備測試夾具的方法。在呼叫測試方法之前立即呼叫。 |
| 2 | tearDown() 在測試方法被呼叫並記錄結果後立即呼叫的方法。即使測試方法引發異常,也會呼叫此方法。 |
| 3 | setUpClass() 在單個類中的測試執行之前呼叫的類方法。 |
| 4 | tearDownClass() 在單個類中的測試執行之後呼叫的類方法。 |
| 5 | run(result = None) 執行測試,並將結果收集到作為 result 傳遞的測試結果物件中。 |
| 6 | skipTest(reason) 在測試方法或 setUp() 中呼叫此方法將跳過當前測試。 |
| 7 | debug() 執行測試但不收集結果。 |
| 8 | shortDescription() 返回測試的一行描述。 |
夾具
可以在 TestCase 類中編寫許多測試。這些測試方法可能需要資料庫連線、臨時檔案或其他需要初始化的資源。這些稱為夾具。TestCase 包含一個特殊的鉤子來配置和清理測試所需的任何夾具。要配置夾具,請覆蓋 setUp()。要進行清理,請覆蓋 tearDown()。
在以下示例中,在 TestCase 類中編寫了兩個測試。它們測試兩個值的加法和減法的結果。setup() 方法根據每個測試的 shortDescription() 初始化引數。teardown() 方法將在每個測試結束時執行。
import unittest
class simpleTest2(unittest.TestCase):
def setUp(self):
self.a = 10
self.b = 20
name = self.shortDescription()
if name == "Add":
self.a = 10
self.b = 20
print name, self.a, self.b
if name == "sub":
self.a = 50
self.b = 60
print name, self.a, self.b
def tearDown(self):
print '\nend of test',self.shortDescription()
def testadd(self):
"""Add"""
result = self.a+self.b
self.assertTrue(result == 100)
def testsub(self):
"""sub"""
result = self.a-self.b
self.assertTrue(result == -10)
if __name__ == '__main__':
unittest.main()
從命令列執行以上程式碼。它會輸出以下內容:
C:\Python27>python test2.py
Add 10 20
F
end of test Add
sub 50 60
end of test sub
.
================================================================
FAIL: testadd (__main__.simpleTest2)
Add
----------------------------------------------------------------------
Traceback (most recent call last):
File "test2.py", line 21, in testadd
self.assertTrue(result == 100)
AssertionError: False is not true
----------------------------------------------------------------------
Ran 2 tests in 0.015s
FAILED (failures = 1)
類夾具
TestCase 類有一個 setUpClass() 方法,可以覆蓋它以在 TestCase 類中單個測試的執行之前執行。類似地,tearDownClass() 方法將在類中所有測試之後執行。這兩個方法都是類方法。因此,它們必須用 @classmethod 指令裝飾。
以下示例演示了這些類方法的使用:
import unittest
class TestFixtures(unittest.TestCase):
@classmethod
def setUpClass(cls):
print 'called once before any tests in class'
@classmethod
def tearDownClass(cls):
print '\ncalled once after all tests in class'
def setUp(self):
self.a = 10
self.b = 20
name = self.shortDescription()
print '\n',name
def tearDown(self):
print '\nend of test',self.shortDescription()
def test1(self):
"""One"""
result = self.a+self.b
self.assertTrue(True)
def test2(self):
"""Two"""
result = self.a-self.b
self.assertTrue(False)
if __name__ == '__main__':
unittest.main()
TestSuite 類
Python 的測試框架提供了一種有用的機制,可以透過該機制根據測試的功能將測試用例例項分組在一起。unittest 模組中的 TestSuite 類提供了這種機制。
建立和執行測試套件涉及以下步驟:
步驟 1 - 建立 TestSuite 類的例項。
suite = unittest.TestSuite()
步驟 2 - 在套件中的 TestCase 類中新增測試。
suite.addTest(testcase class)
步驟 3 - 您還可以使用 makeSuite() 方法從類中新增測試
suite = unittest.makeSuite(test case class)
步驟 4 - 也可以在套件中新增單個測試。
suite.addTest(testcaseclass(""testmethod")
步驟 5 - 建立 TestTestRunner 類的物件。
runner = unittest.TextTestRunner()
步驟 6 - 呼叫 run() 方法以執行套件中的所有測試
runner.run (suite)
TestSuite 類中定義了以下方法:
| 序號 | 方法及描述 |
|---|---|
| 1 | addTest() 在測試套件中新增測試方法。 |
| 2 | addTests() 從多個 TestCase 類中新增測試。 |
| 3 | run() 執行與此套件關聯的測試,並將結果收集到測試結果物件中 |
| 4 | debug() 執行與此套件關聯的測試,但不收集結果。 |
| 5 | countTestCases() 返回此測試物件表示的測試數量 |
以下示例顯示瞭如何使用 TestSuite 類:
import unittest
class suiteTest(unittest.TestCase):
def setUp(self):
self.a = 10
self.b = 20
def testadd(self):
"""Add"""
result = self.a+self.b
self.assertTrue(result == 100)
def testsub(self):
"""sub"""
result = self.a-self.b
self.assertTrue(result == -10)
def suite():
suite = unittest.TestSuite()
## suite.addTest (simpleTest3("testadd"))
## suite.addTest (simpleTest3("testsub"))
suite.addTest(unittest.makeSuite(simpleTest3))
return suite
if __name__ == '__main__':
runner = unittest.TextTestRunner()
test_suite = suite()
runner.run (test_suite)
您可以透過取消註釋這些行並註釋具有 makeSuite() 方法的語句來試驗 addTest() 方法。
TestLoader 類
unittest 包具有 TestLoader 類,用於從類和模組建立測試套件。預設情況下,當呼叫 unittest.main(0 方法時,會自動建立 unittest.defaultTestLoader 例項。但是,顯式例項允許自定義某些屬性。
在以下程式碼中,使用 TestLoader 物件將來自兩個類的測試收集到列表中。
import unittest testList = [Test1, Test2] testLoad = unittest.TestLoader() TestList = [] for testCase in testList: testSuite = testLoad.loadTestsFromTestCase(testCase) TestList.append(testSuite) newSuite = unittest.TestSuite(TestList) runner = unittest.TextTestRunner() runner.run(newSuite)
下表顯示了 TestLoader 類中方法的列表:
| 序號 | 方法及描述 |
|---|---|
| 1 | loadTestsFromTestCase() 返回 TestCase 類中包含的所有測試用例的套件 |
| 2 | loadTestsFromModule() 返回給定模組中包含的所有測試用例的套件。 |
| 3 | loadTestsFromName() 給定字串說明符,返回所有測試用例的套件。 |
| 4 | discover() 透過從指定的起始目錄遞迴進入子目錄來查詢所有測試模組,並返回 TestSuite 物件 |
TestResult 類
此類用於編譯有關已成功測試和遇到失敗的測試的資訊。TestResult 物件儲存一組測試的結果。TestRunner.run() 方法會返回 TestResult 例項。
TestResult 例項具有以下屬性:
| 序號 | 屬性及描述 |
|---|---|
| 1 | Errors 包含 TestCase 例項和儲存格式化回溯的字串的 2 元組的列表。每個元組表示引發意外異常的測試。 |
| 2 | Failures 包含 TestCase 例項和儲存格式化回溯的字串的 2 元組的列表。每個元組表示使用 TestCase.assert*() 方法明確發出失敗訊號的測試。 |
| 3 | Skipped 包含 TestCase 例項和儲存跳過測試原因的字串的 2 元組的列表。 |
| 4 | wasSuccessful() 如果迄今為止執行的所有測試都已透過,則返回 True,否則返回 False。 |
| 5 | stop() 可以呼叫此方法來發出正在執行的測試集應中止的訊號。 |
| 6 | startTestRun() 在執行任何測試之前呼叫一次。 |
| 7 | stopTestRun() 在執行所有測試後呼叫一次。 |
| 8 | testsRun 迄今為止執行的測試總數。 |
| 9 | Buffer 如果設定為 true,則在呼叫 startTest() 和 stopTest() 之間,sys.stdout 和 sys.stderr 將被緩衝。 |
以下程式碼執行測試套件:
if __name__ == '__main__': runner = unittest.TextTestRunner() test_suite = suite() result = runner.run (test_suite) print "---- START OF TEST RESULTS" print result print "result::errors" print result.errors print "result::failures" print result.failures print "result::skipped" print result.skipped print "result::successful" print result.wasSuccessful() print "result::test-run" print result.testsRun print "---- END OF TEST RESULTS"
執行程式碼時顯示以下輸出:
---- START OF TEST RESULTS <unittest.runner.TextTestResult run = 2 errors = 0 failures = 1> result::errors [] result::failures [(<__main__.suiteTest testMethod = testadd>, 'Traceback (most recent call last):\n File "test3.py", line 10, in testadd\n self.assertTrue(result == 100)\nAssert ionError: False is not true\n')] result::skipped [] result::successful False result::test-run 2 ---- END OF TEST RESULTS