品質の高いコードを維持するためには、作成した関数やクラスが意図通りに動作するかを検証する「テスト」が不可欠です。Pythonには、標準ライブラリとして unittest モジュールが組み込まれており、追加のインストールなしで本格的な単体テストを行うことができます。
この記事では、テスト対象の関数を作成し、それに対するテストコードを unittest で実装する手順と、検証に使用する主要なメソッド(アサーション)について解説します。
テスト対象のコード(実装例)
まず、テストを行う対象となる簡単な計算モジュールを作成します。ここでは、足し算を行う関数と、偶数かどうかを判定する関数を定義します。
ファイル名: math_operations.py
def calculate_sum(a, b):
"""2つの数値を足し合わせる"""
return a + b
def is_even_number(number):
"""数値が偶数であればTrueを返す"""
if number % 2 == 0:
return True
return False
このモジュールが正しく動くかどうかのテストを作成していきます。
unittestによるテストコードの実装
unittest を使用する場合、以下のルールに従ってテストコードを記述します。
unittestをインポートする。unittest.TestCaseを継承したテストクラスを作成する。- テストメソッドの名前は必ず
test_で始める(これ以外はテストとして認識されません)。
ファイル名: test_math_operations.py
import unittest
# テスト対象のモジュールをインポート
import math_operations
class TestMathOperations(unittest.TestCase):
"""math_operationsモジュールのテストクラス"""
def test_calculate_sum(self):
"""calculate_sum関数のテスト"""
# 3 + 5 が 8 になることを検証
result = math_operations.calculate_sum(3, 5)
self.assertEqual(result, 8)
# 小数の計算も検証
result_float = math_operations.calculate_sum(1.5, 2.5)
self.assertEqual(result_float, 4.0)
def test_is_even_number(self):
"""is_even_number関数のテスト"""
# 4 は偶数なので True になるはず
self.assertTrue(math_operations.is_even_number(4))
# 5 は奇数なので False になるはず
self.assertFalse(math_operations.is_even_number(5))
# 0 は偶数として扱われる
self.assertTrue(math_operations.is_even_number(0))
if __name__ == "__main__":
unittest.main()
主要なアサーションメソッド一覧
unittest.TestCase クラスには、値を検証するための様々なメソッド(アサーションメソッド)が用意されています。以下に主要なものをまとめます。
| メソッド | テスト内容(検証条件) |
assertEqual(a, b) | a == b であること(等しい) |
assertNotEqual(a, b) | a != b であること(等しくない) |
assertTrue(x) | x が True であること |
assertFalse(x) | x が False であること |
assertIs(a, b) | a is b であること(同一オブジェクト) |
assertIsNot(a, b) | a is not b であること(別オブジェクト) |
assertIsNone(x) | x が None であること |
assertIsNotNone(x) | x が None でないこと |
assertIn(a, b) | a in b であること(a が b に含まれる) |
assertNotIn(a, b) | a not in b であること(含まれない) |
assertIsInstance(a, b) | isinstance(a, b) が True であること(型チェック) |
assertNotIsInstance(a, b) | isinstance(a, b) が False であること |
これらのメソッドは、第一引数に「実際の値」、第二引数に「期待する値」を渡すのが一般的です(assertIn など一部を除く)。
テストの実行方法
作成したテストを実行するには、ターミナル(コマンドプロンプト)で以下のコマンドを入力します。
python test_math_operations.py
実行結果の例:
..
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
..: 2つのテストメソッドが実行され、どちらも成功したことを示します(失敗ならF、エラーならEが表示されます)。OK: 全てのテストが通過した場合に表示されます。
失敗した場合の表示
もしコードにバグがあり、テストが失敗した場合は以下のように詳細が表示されます。
F
======================================================================
FAIL: test_calculate_sum (__main__.TestMathOperations)
----------------------------------------------------------------------
Traceback (most recent call last):
File "test_math_operations.py", line 12, in test_calculate_sum
self.assertEqual(result, 10) # 例えば期待値を間違えた場合
AssertionError: 8 != 10
----------------------------------------------------------------------
Ran 2 tests in 0.001s
FAILED (failures=1)
どのテストメソッドで、どのような不一致(AssertionError: 8 != 10)が起きたかが明確になるため、修正が容易になります。
まとめ
- Pythonで単体テストを行うには標準ライブラリの
unittestを使用します。 unittest.TestCaseを継承したクラスを作成し、test_で始まるメソッド内に検証コードを記述します。- 値の比較には
assertEqual、真偽値の判定にはassertTrue/Falseなどのアサーションメソッドを使用します。 - テストコードを作成しておくことで、リファクタリング(コードの修正)時のバグ混入を即座に検知できます。
