unittest --- 單元測試框架

原始碼:Lib/unittest/__init__.py


(假如你已經熟悉相關基礎的測試概念,你可能會希望跳過以下段落,直接參考 assert 方法清單。)

unittest 原生的單元測試框架最初由 JUnit 開發,和其他程式語言相似有主要的單元測試框架。支援自動化測試,對測試分享安裝與關閉程式碼,集合所有匯總的測試,並且獨立各個測試報告框架。

unittest 用來作為實現支援一些重要的物件導向方法的概念:

test fixture

一個 test fixture 代表執行一個或多個測試所需要的準備,以及其他相關清理操作,例如可以是建立臨時性的或是代理用 (proxy) 資料庫、目錄、或是啟動一個伺服器程序。

test case(測試用例)

一個 test case 是一個獨立的單元測試。這是用來確認一個特定設定的輸入的特殊回饋。unittest 提供一個基礎類別,類別 TestCase,可以用來建立一個新的測試條例。

test suite(測試套件)

test suite 是一個搜集測試條例,測試套件,或是兩者皆有。它需要一起被執行並用來匯總測試。

test runner(測試執行器)

test runner 是一個編排測試執行與提供結果給使用者的一個元件。執行器可以使用圖形化介面,文字介面或是回傳一個特別值用來標示出執行測試的結果。

也參考

doctest 模組

另一個執行測試的模組,但使用不一樣的測試方法與規範。

Simple Smalltalk Testing: With Patterns

Kent Beck 的原始論文討論使用 unittest 這樣模式的測試框架。

pytest

第三方的單元測試框架,但在撰寫測試時使用更輕量的語法。例如: assert func(10) == 42

The Python Testing Tools Taxonomy

一份詳細的 Python 測試工具列表,包含 functional testing 框架和mock object 函式庫。

Testing in Python Mailing List

一個專門興趣的群組用來討論 Python 中的測試方式與測試工具。

The script Tools/unittestgui/unittestgui.py in the Python source distribution is a GUI tool for test discovery and execution. This is intended largely for ease of use for those new to unit testing. For production environments it is recommended that tests be driven by a continuous integration system such as Buildbot, Jenkins, GitHub Actions, or AppVeyor.

簡單範例

unittest 模組提供一系列豐富的工具用來建構與執行測試。本節將展示這一系列工具中一部份,它們已能滿足大部份使用者需求。

這是一段簡短的腳本用來測試 3 個字串方法:

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

測試用例 (test case) 可以透過繼承 unittest.TestCase 類別來建立。這裡定義了三個獨立的物件方法,名稱皆以 test 開頭。這樣的命名方式能告知 test runner 哪些物件方法為定義的測試。

每個測試的關鍵為呼叫 assertEqual() 來確認是否為期望的結果; assertTrue() 或是 assertFalse() 用來驗證一個條件式; assertRaises() 用來驗證是否觸發一個特定的 exception。使用這些物件方法來取代 assert 陳述句,將能使 test runner 收集所有的測試結果並產生一個報表。

The setUp() and tearDown() methods allow you to define instructions that will be executed before and after each test method. They are covered in more detail in the section Organizing test code.

最後將顯示一個簡單的方法去執行測試 unittest.main() 提供一個命令列介面測試腳本。當透過命令列執行,輸出結果將會像是:

...
----------------------------------------------------------------------
Ran 3 tests in 0.000s

OK

在測試時加入 -v 選項將指示 unittest.main() 提高 verbosity 層級,產生以下的輸出:

test_isupper (__main__.TestStringMethods.test_isupper) ... ok
test_split (__main__.TestStringMethods.test_split)