Cou氏の徒然日記

ほのぼの日記ブログです。

Python3の学習 その20 (unittest:単体テスト)

Python

今回はunittestについて。

テスト駆動型開発をするうえで、テストコードも必ずセットで書くことが多いですが、その中の一つのやり方が、unittestモジュールを使うことのようです。

 

■ unittestモジュール

まずは今回テストする関数を作成。

unittest1.py に ruijou (累乗を返す) 関数を作成。

def ruijou(a, b):
    return a ** b

 

上記のテストを作成します。

test_unittest1.py を作り、unittestモジュールをインポート。

あとはテストクラスを作成するだけです。

import unittest
from unittest1 import ruijou

class ruijouTest(unittest.TestCase):
    def test_2_5(self):
        actual = ruijou(2, 5)
        expected = 32
        self.assertEqual(actual, expected)

    def test_fail_2_3(self):
        actual = ruijou(2, 3)
        expected = 6
        self.assertEqual(actual, expected)

    def test_2_6(self):
        actual = ruijou(2, 6)
        expected = 64
        self.assertEqual(actual, expected)

if __name__ == "__main__":
    unittest.main()

 

これを試しに実行してみると…

coublood@penguin:~/python$ python3 test_unittest1.py 
..F
======================================================================
FAIL: test_fail_2_3 (__main__.ruijouTest.test_fail_2_3)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/coublood/python/test_unittest1.py", line 13, in test_fail_2_3
    self.assertEqual(actual, expected)
AssertionError: 8 != 6

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

FAILED (failures=1)

テスト実行数も「Run 3 tests」となっていることから、全部実行されており、ダメだったテストのみ、エラーとして出ていることが確認できます。

 

■ 事前実行、事後実行関数

単体テストを実行する場合、その関数を実行する前に実行しておかないといけない処理、その関数を実行した後に実行しないといけない処理もあります。

それらは以下の関数を準備することで実行できるようです。

 

[事前実行・事後実行関数]
  • setUp:テストごとに、テストの前に実行
  • setUpClass:クラスの最初のテストの前に1度だけ実行
  • tearDown:テストごとに、テストの後に実行
  • tearDownClass:クラスの全部のテストが終わった後に1度だけ実行

 

どういう順番で実行されているかを試してみるために、実行されたらわかるようにprint関数を定義してみます。

import unittest

class functionTest(unittest.TestCase):
    def setUp(self):
        print('setUp')
    
    def setUpClass():
        print('setUpClass')

    def tearDown(self):
        print('tearDown')

    def tearDownClass():
        print('tearDownClass')

    def test1(self):
        print('test1')

    def test2(self):
        print('test2')

    def test3(self):
        print('test3')

if __name__ == '__main__':
    unittest.main()

このテストを実行してみると…

coublood@penguin:~/python$ python3 test_unittest2.py 
setUpClass
setUp
test1
tearDown
.setUp
test2
tearDown
.setUp
test3
tearDown
.tearDownClass

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

OK

確かに書かれているとおりに実行されているようです。