仕様・テスト・デバッグ
プログラムを作成する際には、仕様(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" + 53. 論理エラー(Logic Error)
構文も実行も問題ないが、計算結果が正しくない場合です。最も発見が難しいエラーです。
python
# 論理エラーの例:摂氏から華氏への変換def celsius_to_fahrenheit(c): # 正しい式: (c * 9/5) + 32 return c * 9 + 32 # バグ!# テストを書いていれば発見できるassert celsius_to_fahrenheit(0) == 32 # AssertionError! → バグ発見デバッグの具体例
print デバッグ
最も基本的なデバッグ方法は、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() 関数を使わずに実装してください。