單元測試是測試驅動開發 (TDD) 核心,Python 內建 unittest 提供豐富斷言、自動發現、fixture 機制。本文以自訂 Dict 類別為例,示範測試類別撰寫、執行方式、setUp/tearDown 生命週期與覆蓋率建議。
class Dict(dict):
def __init__(self, **kw): super(Dict, self).__init__(**kw)
def __getattr__(self, key):
try: return self[key]
except KeyError: raise AttributeError("'Dict' object has no attribute '%s'" % key)
def __setattr__(self, key, value): self[key] = value
import unittest
from mydict import Dict
class TestDict(unittest.TestCase):
def setUp(self): print('setUp...')
def tearDown(self): print('tearDown...')
def test_init(self):
d = Dict(a=1, b='test')
self.assertEqual(d.a, 1)
self.assertEqual(d.b, 'test')
self.assertTrue(isinstance(d, dict))
def test_key(self):
d = Dict()
d['key'] = 'value'
self.assertEqual(d.key, 'value')
def test_attr(self):
d = Dict()
d.key = 'value'
self.assertTrue('key' in d)
self.assertEqual(d['key'], 'value')
def test_keyerror(self):
d = Dict()
with self.assertRaises(KeyError):
_ = d['empty']
def test_attrerror(self):
d = Dict()
with self.assertRaises(AttributeError):
_ = d.empty
# 方式一:直接執行腳本 (檔案末尾加入 unittest.main())
$ python mydict_test.py
# 方式二:模組模式 (推薦,支援批量發現)
$ python -m unittest mydict_test
.....
----------------------------------------------------------------------
Ran 5 tests in 0.001s
OK
| 方法 | 用途 |
|---|---|
| assertEqual(a, b) | a == b |
| assertNotEqual(a, b) | a != b |
| assertTrue(x) / assertFalse(x) | 布林判斷 |
| assertIs(a, b) / assertIsNot(a, b) | 同一物件身分 |
| assertIsNone(x) / assertIsNotNone(x) | None 判斷 |
| assertIn(a, b) / assertNotIn(a, b) | 成員關係 |
| assertRaises(Error, callable, *args) | 預期拋出異常 |
| assertAlmostEqual(a, b, places=7) | 浮點數近似相等 |