單元測試框架 - 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.stdoutsys.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
廣告

© . All rights reserved.