[Python] Unit Test 單元測試
Python 很久以前就開始內建 unittest
了。但一直都沒有用,只有偷懶一直用 assert
(該死!)
官方舉的一個簡單例子,可以測試一下(記得不要跟我一樣白痴把檔名取成 unittest.py):
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
開頭的,都會被視為測試程式執行。
Command Line
如果不想把 unittest.main()
寫進 __main__
的話,可以使用指令執行:
python -m unittest <檔名>
或者乾脆用 discover
讓它自己尋找:
python -m unittest discover
也可以再進一步指定:
- -s: start directory
- -p: pattern
python -m unittest discover -s project_directory -p "*_test.py"
python -m unittest discover project_directory "*_test.py"
setUp()
and tearDown()
當然進一步有時我們會希望每個測式前後進行一些動作,這時就需要用上 setUp()
和 tearDown()
了。
- 將測試前的準備工作寫在
setUp()
裡,在每一個 test case 開始前執行。setUp()
固定會在 test case 開始前被呼叫。 - 將測試後的清理工作寫在
tearDown()
裡。tearDown()
固定會在每一個 test case 結束後被呼叫。
再複製一下官方的程式:
import unittest
class WidgetTestCase(unittest.TestCase):
def setUp(self):
self.widget = Widget('The widget')
def tearDown(self):
self.widget.dispose()
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')
Assertion
然後測式碼裡面的斷言(assertion),常用的:
assertTrue(expr, msg=None)
assertFalse(expr, msg=None)
assertEqual(first, second, msg=None)
assertNotEqual(first, second, msg=None)
剩下的之後再寫吧!