文章

第29天:單元測試

課程簡介

單元測試是對程式的最小單元(通常是一個函數或類別方法)進行獨立測試,以確保程式的行為符合預期。
Python 提供了 unittest 模組,內建了豐富的工具來編寫和執行單元測試。
今天,我們將學習如何使用 unittest 模組來進行基礎的單元測試,確保程式碼的穩定性和可靠性。


學習內容

1. 什麼是單元測試

單元測試是自動化測試的一部分,專注於測試單一的程式碼單元(如函數、方法),通常會隔離這個單元並對其進行功能測試。
單元測試的目標是捕捉程式中的潛在錯誤,以便及早修復。


2. 使用 unittest 模組

unittest 是 Python 標準庫中提供的測試框架,支援測試用例(test case)、測試套件(test suite)、測試執行(test runner)等功能。

範例結構:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import unittest

# 被測試的函數
def add(a, b):
    return a + b

# 測試用例
class TestMathFunctions(unittest.TestCase):

    # 測試加法
    def test_add(self):
        self.assertEqual(add(2, 3), 5)
        self.assertEqual(add(-1, 1), 0)
        self.assertEqual(add(0, 0), 0)

# 執行測試
if __name__ == "__main__":
    unittest.main()

3. 常用的測試方法

unittest 提供了許多常用的測試方法,以下是一些常見的測試方法:

  • assertEqual(a, b):檢查 a 是否等於 b
  • assertNotEqual(a, b):檢查 a 是否不等於 b
  • assertTrue(x):檢查 x 是否為 True
  • assertFalse(x):檢查 x 是否為 False
  • assertIn(a, b):檢查 a 是否存在於 b
  • assertRaises(Error, func, *args, **kwargs):檢查是否拋出指定的錯誤

範例:

1
2
3
4
5
6
7
8
9
10
class TestAssertions(unittest.TestCase):

    def test_assert_methods(self):
        self.assertEqual(3 + 2, 5)
        self.assertNotEqual(3 * 2, 5)
        self.assertTrue(3 < 5)
        self.assertFalse(3 > 5)
        self.assertIn('a', 'apple')
        with self.assertRaises(ValueError):
            int("invalid")

4. 測試前後置處理:setUptearDown

可以使用 setUptearDown 方法來分別在每個測試方法前後進行初始化和清理操作。這樣可以確保測試環境的一致性。

範例:

1
2
3
4
5
6
7
8
9
10
class TestSetupTeardown(unittest.TestCase):

    def setUp(self):
        print("測試前準備工作")

    def tearDown(self):
        print("測試後清理工作")

    def test_example(self):
        self.assertEqual(2 + 2, 4)

5. 使用測試套件(Test Suite)

可以將多個測試用例組合成一個測試套件,方便批量執行。

範例:

1
2
3
4
5
6
7
8
9
def suite():
    suite = unittest.TestSuite()
    suite.addTest(TestMathFunctions("test_add"))
    suite.addTest(TestAssertions("test_assert_methods"))
    return suite

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

6. Mock 與依賴隔離

在單元測試中,有時需要模擬某些功能(如資料庫查詢或網路請求)來隔離測試單元。可以使用 unittest.mock 模組來模擬這些依賴。

範例:

1
2
3
4
5
6
7
8
from unittest.mock import Mock

def get_data():
    return "實際資料"

# 使用 Mock 物件
mocked_get_data = Mock(return_value="模擬資料")
print(mocked_get_data())  # 輸出 "模擬資料"

教學重點

  • 單元測試概念:理解單元測試的作用及其重要性。
  • 使用 unittest:學習如何撰寫基本的測試用例,並運行單元測試。
  • 測試方法:掌握常用的測試方法,進行各種條件的測試。
  • 前後置處理:利用 setUptearDown 進行測試環境的初始化和清理。
  • 隔離測試依賴:使用 Mock 來模擬依賴,實現單元測試的隔離性。

任務

  1. 實現一個簡單的計算器函數庫(包含加法、減法、乘法、除法),並為每個函數編寫對應的單元測試。
  2. 使用 setUptearDown 方法,測試前創建一個臨時的列表,測試後清理該列表。
  3. 使用 Mock 模擬一個外部 API 的回應,並檢查程式在使用模擬資料的情況下能正常運行。
本文章以 CC BY 4.0 授權