✅
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