✅
Python Unittestについての備忘録
最近、Pythonでテストコードを書く機会があったので
その際に学んだことをここに残していく
unittest とは?
Pythonの標準ライブラリに含まれている
テストコード
構造
unittest
では、テストケースはunittest.TestCase
クラスのインスタンス
自分でテストケースを作る場合にはTestCase
のサブクラスを作成する
unittest.main()
を呼び出すことで、モジュール内の全テストケースを実行してくれる
import unittest
class TestCooking(unittest.TestCase): # TestCaseを継承
# テストメソッドの記述
テストメソッド
テストメソッドは先頭をtest
で始める
def test_cooking_calculateSeasoning(self) -> None:
# ここに具体的なテスト内容を書く
テスト開始前・実施後に実行したい処理
setUp()
: テスト実行前に自動で呼び出される
※setUp()
で例外発生した場合は、テストに問題があると判断されテストメソッドは実行されない
tearDown()
: テスト実行後に呼び出される
※setUp()
が成功した場合は、テストメソッドの成功・失敗にかかわらず実行される
import unittest
class TestCooking(unittest.TestCase): # TestCaseを継承
def setUp(self):
# 実行する内容
def tearDown(self):
# 何も実行しないでpassすることもできる
pass
テスト用の関数たち(以下に書いたもの以外にもいっぱいある)
メソッド | 判定 |
---|---|
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 |
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) |
def test_cooking_calculateSeasoning(self) -> None:
# テストしたいクラス
cooking = Cooking()
# 確認したいクラスのメソッドの実行結果
calculatedSeasoning = cooking.calculateSeasoning()
self.assertEqual(
calculatedSeasoning,
"10g",
)
mock
モックとは実際のオブジェクトやコンポーネント等を模造したもの
例えば以下のようなクラスがあった時
class Member:
def getStatus(self) -> dict:
# API実行してメンバーのステータスを取得
apiResponse = ApiUtil.getMemberStatus()
return {
"type": apiResponse.get("type"),
"plan": apiResponse.get("plan"),
}
def isLimited(self) -> bool:
contents = self.getStatus()
if contents["type"] is None or contents["plan"] is None:
return True
return False
Member
クラスのisLimited()
をテストしたいけど、、、
テスト実行されるごとにgetStatus()
が実行されてAPIが呼び出される、、、
→ getStatus()の部分をモックにしてテストを行う
import unittest
from unittest.mock import patch
class TestMember(unittest.TestCase):
# patchデコレータでテスト対象のモジュール内のクラスやオブジェクトをモックにする
@patch('ApiUtil.getMemberStatus')
def test_getStatus(self, mock_get_member_status):
# ApiUtil.getMemberStatus()のモックを設定
mock_get_member_status.return_value = {"type": "premium", "plan": "annual"}
member = Member()
result = member.getStatus()
self.assertEqual(result, {"type": "premium", "plan": "annual"})
モックを使うことで外部APIへの依存をせずにテストを行うことができる
Discussion