今日はPythonのunittestについて学び、Pythonのユニットテストのサンプルプログラムを見てみましょう。前回のチュートリアルでは、python zip functionについて学びました。
Python unittest
Python unittestモジュールは、ソースコードの単位をテストするために使用されます。プロジェクトをテストする必要があると仮定します。関数がどのようなデータを返すかを知っています。大量のコードを書いた後、出力が正しいかどうかを確認する必要があります。通常、私たちが行うことは、出力を表示してそれを参照出力ファイルと一致させるか、出力を手動で確認することです。この手間を軽減するために、Pythonはunittestモジュールを導入しました。このモジュールを使用すると、いくつかの簡単なコードで関数の出力を確認できます。このチュートリアルでは、Python unittestモジュールの基本的な使用法について説明し、いくつかのPythonユニットテストケースを書いてクラスの機能をテストします。
Python Unit Testの例のソース
まず、ユニットテストを行うためのコードを書かなければなりません。私たちは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の構造
では、ユニットテストのコードの書き方を学びましょう。個々のテストケースは、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モジュールの実行方法
PyCharm IDEを使用している場合、unittestモジュールを実行するには、ctrl+shift+F10を単純に押すことができます。それ以外の場合は、コマンドプロンプトを使用してこのモジュールを実行できます。たとえば、ユニットテスト用のファイルの名前をBasic_Test.py
としました。したがって、Pythonのunittestを実行するコマンドは次のようになります:$python3.6 -m unittest Basic_Test.Testing
冗長な出力を表示したい場合は、次のコマンドになります:$python3.6 -m unittest -v Basic_Test.Testing
PyCharmを使用すると、以下の出力を取得できます。
Pythonユニットテストの結果と基本的な機能
このunittestには3つの可能な結果があります。以下にそれらを示します。
- OK:すべてのテストケースがパスした場合、出力にはOKが表示されます。
- Failure:テストケースのいずれかが失敗し、AssertionError例外が発生した場合
- Error: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
# これがテストしたいクラスです。したがって、それをインポートする必要があります
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
# Person.set_name関数をチェックするテストケース関数
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):
# 名前を初期化する
name = 'name' + str(i)
# 名前をリスト変数に保存する
self.user_name.append(name)
# 関数から取得したユーザーIDを取得する
user_id = self.person.set_name(name)
# 取得したユーザーIDがnullかどうかをチェックする
self.assertIsNotNone(user_id) # null user id will fail the test
# ユーザーIDをリストに保存する
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")
# Person.get_name関数をチェックするテストケース関数
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 < length:
# 2つの名前が一致しない場合、テストケースは失敗します
self.assertEqual(self.user_name[i], self.person.get_name(self.user_id[i]))
else:
print("Testing for get_name no user test")
# 長さが超過する場合は、'no such user'タイプのメッセージをチェックします
self.assertEqual('There is no such user', self.person.get_name(i))
print("\nFinish get_name test\n")
if __name__ == '__main__':
# 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 の unittest チュートリアルに関するすべてが終わりです。詳細は、公式ドキュメントを読んでください。その他の質問はコメントボックスをご利用ください。 🙂
Source:
https://www.digitalocean.com/community/tutorials/python-unittest-unit-test-example