記事一覧へ戻る 本の順番で続きを読む

テストとデバッグ - 品質を保証するコード

Python3中級 | 2026/02/18 15:44

テストとデバッグ

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() で対話的デバッグ