1-4

テストとデバッグ

仕様・テスト・デバッグ

プログラムを作成する際には、仕様(spec)→ テスト → 実装 → デバッグ というサイクルが基本です。

  • 仕様(specification): プログラムがどのように動作すべきかの定義
  • テスト(test): 仕様通りに動作しているか確認すること
  • デバッグ(debugging): バグ(誤り)を見つけて修正すること
開発サイクル📋仕様策定テスト作成💻実装🐛デバッグテスト失敗 → 修正して再テスト🎉 テスト成功!

正しいプログラムを書くためには、コードを書く前に「何をすべきか」を明確にしておくことが大切です。

assert文

assert 文は、条件が True であることを確認するための文法です。条件が False の場合、AssertionError が発生します。

python
assert 1 + 1 == 2        # OK(例外が発生しない)assert 2 + 2 == 5        # AssertionError!

テストを書くには、関数を実装したら assert で期待結果を確認します。

python
def square(x):    return x * x# テストassert square(3) == 9assert square(-2) == 4assert square(0) == 0print("全てのテストに合格しました!")

テストを先に書く(テスト駆動開発)

良い習慣として、関数を実装する前にテストを書いておく方法があります(TDD: Test Driven Development)。

python
# 1. まずテストを書く(この時点では関数未定義)# assert add(1, 2) == 3# assert add(-1, 1) == 0# 2. テストが通るように実装するdef add(a, b):    return a + b# 3. テストを実行して確認assert add(1, 2) == 3assert add(-1, 1) == 0print("テスト完了!")

エラーの分類

プログラムのエラーは主に3種類に分類されます。

1. 構文エラー(SyntaxError)

コードの文法が正しくない場合に発生します。プログラムは一切実行されません。

python
# SyntaxError の例def foo(    return 1    # 括弧が閉じられていない    x = 1 +        # 右辺が不完全

2. 実行時エラー(RuntimeError / Exception)

構文は正しいが、実行中に問題が発生する場合です。

python
# ZeroDivisionError(ゼロ除算)1 / 0# NameError(未定義の変数)print(undefined_variable)# TypeError(型の不一致)"hello" + 5

3. 論理エラー(Logic Error)

構文も実行も問題ないが、計算結果が正しくない場合です。最も発見が難しいエラーです。

python
# 論理エラーの例:摂氏から華氏への変換def celsius_to_fahrenheit(c):    # 正しい式: (c * 9/5) + 32    return c * 9 + 32   # バグ!# テストを書いていれば発見できるassert celsius_to_fahrenheit(0) == 32     # AssertionError! → バグ発見

デバッグの具体例

最も基本的なデバッグ方法は、print で中間値を出力することです。

python
def mystery(n):    result = 0    for i in range(n):        result += i    return result# デバッグ用に print を追加def mystery_debug(n):    result = 0    for i in range(n):        print(f"i={i}, result={result}")  # 中間値を確認        result += i    return resultmystery_debug(5)

境界値テスト

テストケースには境界値(エッジケース)を含めることが重要です。

python
def factorial(n):    """n! を返す(n >= 0)"""    if n == 0:        return 1    return n * factorial(n - 1)# 通常のテストassert factorial(5) == 120assert factorial(3) == 6# 境界値テストassert factorial(0) == 1    # n=0 のケースassert factorial(1) == 1    # n=1 のケースprint("全テスト完了!")

練習: バグを修正する

基礎

以下のコードにはバグがあります。テストを実行してバグを見つけ、修正してください。

python
def average(a, b, c):    """3つの数の平均を返す"""    return a + b + c / 3   # バグあり!# テストassert average(1, 2, 3) == 2.0assert average(0, 0, 0) == 0.0assert average(3, 6, 9) == 6.0

練習: 最大値関数

基礎

3つの引数の中で最大値を返す関数 max3(a, b, c) を定義してください。組み込みの max() 関数を使わずに実装してください。