pcwu's TIL Notes


[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

也可以再進一步指定:

python -m unittest discover -s project_directory -p "*_test.py"
python -m unittest discover project_directory "*_test.py"

setUp() and tearDown()

當然進一步有時我們會希望每個測式前後進行一些動作,這時就需要用上 setUp()tearDown() 了。

再複製一下官方的程式:

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),常用的:

剩下的之後再寫吧!

Reference