unittest 組織測試代碼

2022-08-02 10:56 更新

單元測試的基本構(gòu)建塊是測試用例 — 必須設(shè)置和檢查其正確性的單個方案。在 ?unittest ?中,測試用例由 unittest.TestCase 實例表示。要創(chuàng)建自己的測試用例,您必須編寫 TestCase 的子類或使用 FunctionTestCase。

TestCase 實例的測試代碼應(yīng)該完全獨立,這樣它既可以單獨運行,也可以與任意數(shù)量的其他測試用例任意組合運行。

最簡單的 TestCase 子類將簡單地實現(xiàn)一個測試方法(即名稱以?test ?) 開頭的方法,以便執(zhí)行特定的測試代碼:

import unittest

class DefaultWidgetSizeTestCase(unittest.TestCase):
    def test_default_widget_size(self):
        widget = Widget('The widget')
        self.assertEqual(widget.size(), (50, 50))

請注意,為了測試某些內(nèi)容,我們使用 TestCase 基類提供的 ?assert*() ?方法之一。如果測試失敗,將引發(fā)異常并帶有解釋性消息,并且 ?unittest ?會將測試用例標識為失敗。任何其他異常都將被視為錯誤。

測試可能很多,并且它們的設(shè)置可能是重復的。幸運的是,我們可以通過實現(xiàn)一個名為 setUp() 的方法來分解設(shè)置代碼,測試框架將為我們運行的每個測試自動調(diào)用該方法:

import unittest

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

    def test_default_widget_size(self):
        self.assertEqual(self.widget.size(), (50,50),
                         'incorrect default size')

    def test_widget_resize(self):
        self.widget.resize(100,150)
        self.assertEqual(self.widget.size(), (100,150),
                         'wrong size after resize')
注意
各種測試的運行順序是通過相對于字符串的內(nèi)置排序?qū)y試方法名稱進行排序來確定的。

如果 setUp() 方法在測試運行時引發(fā)異常,框架將認為測試已遭受錯誤,并且不會執(zhí)行測試方法。

類似地,我們可以提供一個 tearDown() 方法,該方法在測試方法運行后進行整理:

import unittest

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

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

如果 setUp() 成功,則無論測試方法是否成功,都將運行 tearDown()。

這種用于測試代碼的工作環(huán)境稱為測試夾具。創(chuàng)建一個新的 TestCase 實例作為用于執(zhí)行每個單獨的測試方法的唯一測試夾具。因此每次測試都會調(diào)用一次 setUp()、tearDown() 和 __init__()。

建議您使用 TestCase 實現(xiàn),根據(jù)測試的功能將測試組合在一起。unittest為此提供了一種機制:測試套件,由unittestTestSuite類表示。在大多數(shù)情況下,調(diào)用unittest.main()將做正確的事情,并為您收集所有模塊的測試用例并執(zhí)行它們。

但是,如果要自定義測試套件的構(gòu)建,可以自己操作:

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())

您可以將測試用例和測試套件的定義與它們要測試的代碼(例如 ?widget.py?)放在相同的模塊中,但是將測試代碼放在單獨的模塊中有幾個優(yōu)點,例如 ?test_widget.py? :

  • 測試模塊可以從命令行獨立運行。

  • 測試代碼可以更容易地與附帶的代碼分開。

  • 在沒有充分理由的情況下更改測試代碼以適應(yīng)它測試的代碼的誘惑較小。
  • 與它測試的代碼相比,測試代碼的修改頻率應(yīng)該低得多。
  • 測試的代碼可以更容易地重構(gòu)。
  • 無論如何,用C編寫的模塊的測試必須在單獨的模塊中,那么為什么不保持一致呢?
  • 如果測試策略發(fā)生更改,則無需更改源代碼。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號