テストとデバッグ
unittest の基本
import unittest
def add(a, b):
return a + b
def divide(a, b):
if b == 0:
raise ValueError("0で割れません")
return a / b
class TestCalculator(unittest.TestCase):
def test_add(self):
self.assertEqual(add(2, 3), 5)
self.assertEqual(add(-1, 1), 0)
def test_divide(self):
self.assertAlmostEqual(divide(10, 3), 3.333, places=3)
def test_divide_by_zero(self):
with self.assertRaises(ValueError):
divide(10, 0)
def setUp(self):
"""各テスト前に実行"""
self.data = [1, 2, 3]
def tearDown(self):
"""各テスト後に実行"""
pass
if __name__ == '__main__':
unittest.main()
pytest の基本
pytestはより簡潔にテストが書けるフレームワークです。
# test_calc.py
def add(a, b):
return a + b
def test_add():
assert add(2, 3) == 5
assert add(-1, 1) == 0
assert add(0, 0) == 0
def test_add_float():
result = add(0.1, 0.2)
assert abs(result - 0.3) < 1e-9
import pytest
def test_divide_by_zero():
with pytest.raises(ValueError):
divide(10, 0)
パラメータ化テスト
import pytest
@pytest.mark.parametrize("a, b, expected", [
(2, 3, 5),
(-1, 1, 0),
(0, 0, 0),
(100, -50, 50),
])
def test_add_params(a, b, expected):
assert add(a, b) == expected
フィクスチャ
import pytest
@pytest.fixture
def sample_users():
return [
{"name": "太郎", "age": 25},
{"name": "花子", "age": 30},
]
def test_user_count(sample_users):
assert len(sample_users) == 2
def test_user_name(sample_users):
assert sample_users[0]["name"] == "太郎"
モック
from unittest.mock import patch, MagicMock
def get_user_from_api(user_id):
import requests
response = requests.get(f'https://api.example.com/users/{user_id}')
return response.json()
@patch('requests.get')
def test_get_user(mock_get):
mock_get.return_value.json.return_value = {
'id': 1, 'name': '太郎'
}
result = get_user_from_api(1)
assert result['name'] == '太郎'
mock_get.assert_called_once()
デバッグ技法
# breakpoint()(Python 3.7+)
def complex_calculation(data):
result = []
for item in data:
processed = item * 2
breakpoint() # ここでデバッガが起動
result.append(processed)
return result
# pdb コマンド:
# n(ext) - 次の行
# s(tep) - ステップイン
# c(ontinue) - 続行
# p 変数名 - 変数の値を表示
# l(ist) - ソースコード表示
# q(uit) - 終了
まとめ
unittestは標準ライブラリのテストフレームワークpytestはより簡潔で強力なサードパーティフレームワーク@pytest.mark.parametrizeでパラメータ化テストunittest.mock.patchで外部依存をモック化breakpoint()で対話的デバッグ