Python unittest - 単体テストの例
今日は、python unittest について学び、python 単体テストのサンプル プログラムを見ていきます。前のチュートリアルでは、python zip 関数について学びました。
Python単体テスト
Python unittest モジュールは、ソース コードのユニットをテストするために使用されます。プロジェクトをテストする必要があるとします。関数が返すデータの種類はわかっています。巨大なコードを書いた後は、出力が正しいかどうかをチェックする必要があります。通常、出力を印刷して参照出力ファイルと照合するか、出力を手動で確認します。この苦痛を軽減するために、Python は unittest モジュールを導入しました。このモジュールを使用すると、簡単なコードで関数の出力を確認できます。このチュートリアルでは、Python unittest モジュールの基本的な使用法について説明し、クラス関数をテストするための Python 単体テスト ケースをいくつか書きます。
Python ユニット テストのサンプル ソース
まず、単体テストを行うためのコードを書く必要があります。 Python クラスがあります。このクラスの主な目的は、人の名前を保存および取得することです。そのため、データを格納する set_name()
関数と、クラスから名前を取得する get_name()
関数を記述します。
class Person:
name = []
def set_name(self, user_name):
self.name.append(user_name)
return len(self.name) - 1
def get_name(self, user_id):
if user_id >= len(self.name):
return 'There is no such user'
else:
return self.name[user_id]
if __name__ == '__main__':
person = Person()
print('User Abbas has been added with id ', person.set_name('Abbas'))
print('User associated with id 0 is ', person.get_name(0))
クラス ファイルに Person.py
という名前を付けました。そして、上記のコードの出力は以下のようになります。
$ python3.6 Person.py
User Abbas has been added with id 0
User associated with id 0 is Abbas
$
Python 単体テスト構造
それでは、単体テストのコーディング方法を学びましょう。個々のテストケースは、unittest.TestCase
をサブクラス化することによって作成されます。適切な関数をオーバーライドまたは追加することで、テストするロジックを追加できます。次のコードは、a が b と等しい場合に成功します。
import unittest
class Testing(unittest.TestCase):
def test_string(self):
a = 'some'
b = 'some'
self.assertEqual(a, b)
def test_boolean(self):
a = True
b = True
self.assertEqual(a, b)
if __name__ == '__main__':
unittest.main()
Python unittest モジュールの実行方法

Python 単体テストの結果と基本機能
この単体テストには 3 つの結果が考えられます。以下にそれらを示します。
- OK: すべてのテスト ケースに合格すると、出力に OK が表示されます。
- 失敗: いずれかのテスト ケースが失敗し、AssertionError 例外が発生した場合
- エラー: AssertionError 以外の例外が発生した場合
unittest モジュールの下にいくつかの関数があります。それらは以下にリストされています。
Method | Checks that |
---|---|
assertEqual(a,b) | a==b |
assertNotEqual(a,b) | a != b |
assertTrue(x) | bool(x) is True |
assertFalse(x) | bool(x) is False |
assertIs(a,b) | a is b |
assertIs(a,b) | a is b |
assertIsNot(a, b) | a is not b |
assertIsNone(x) | x is None |
assertIsNotNone(x) | x is not None |
assertIn(a, b) | a in b |
assertNotIn(a, b) | a not in b |
assertIsInstance(a, b) | isinstance(a, b) |
assertNotIsInstance(a, b) | not isinstance(a, b) |
Python 単体テストの例
今度は、ソース クラス Person
の単体テストを作成します。このクラスでは、get_name()
と set_name()
という 2 つの関数を実装しています。ここで、unittest
を使用してこれらの関数をテストします。そのため、これら 2 つの機能に対して 2 つのテスト ケースを設計しました。次のコードを見てください。簡単に理解できます。
import unittest
# This is the class we want to test. So, we need to import it
import Person as PersonClass
class Test(unittest.TestCase):
"""
The basic class that inherits unittest.TestCase
"""
person = PersonClass.Person() # instantiate the Person Class
user_id = [] # variable that stores obtained user_id
user_name = [] # variable that stores person name
# test case function to check the Person.set_name function
def test_0_set_name(self):
print("Start set_name test\n")
"""
Any method which starts with ``test_`` will considered as a test case.
"""
for i in range(4):
# initialize a name
name = 'name' + str(i)
# store the name into the list variable
self.user_name.append(name)
# get the user id obtained from the function
user_id = self.person.set_name(name)
# check if the obtained user id is null or not
self.assertIsNotNone(user_id) # null user id will fail the test
# store the user id to the list
self.user_id.append(user_id)
print("user_id length = ", len(self.user_id))
print(self.user_id)
print("user_name length = ", len(self.user_name))
print(self.user_name)
print("\nFinish set_name test\n")
# test case function to check the Person.get_name function
def test_1_get_name(self):
print("\nStart get_name test\n")
"""
Any method that starts with ``test_`` will be considered as a test case.
"""
length = len(self.user_id) # total number of stored user information
print("user_id length = ", length)
print("user_name length = ", len(self.user_name))
for i in range(6):
# if i not exceed total length then verify the returned name
if i < length:
# if the two name not matches it will fail the test case
self.assertEqual(self.user_name[i], self.person.get_name(self.user_id[i]))
else:
print("Testing for get_name no user test")
# if length exceeds then check the 'no such user' type message
self.assertEqual('There is no such user', self.person.get_name(i))
print("\nFinish get_name test\n")
if __name__ == '__main__':
# begin the unittest.main()
unittest.main()
unittest モジュールは、定義された順序ではなく、名前の順序でテスト関数を実行することに注意してください。 set_name テストを最初に実行したいので、テスト ケース関数に test_0_set_name
および test_1_get_name
という名前を付けました。
Python 単体テストの出力例

$ python3.6 -m unittest -v PersonTest.Test
test_0_set_name (PersonTest.Test) ... Start set_name test
user_id length = 4
[0, 1, 2, 3]
user_name length = 4
['name0', 'name1', 'name2', 'name3']
Finish set_name test
ok
test_1_get_name (PersonTest.Test) ...
Start get_name test
user_id length = 4
user_name length = 4
Testing for get_name no user test
Testing for get_name no user test
Finish get_name test
ok
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
$
これで Python 単体テストのチュートリアルは終わりです。詳細については、公式ドキュメントを参照してください。さらに質問がある場合は、コメント ボックスを使用してください。 :)