Pythonでは関数の動作例をドキュメントに書き、それをそのままテストとして実行できる「doctest」という仕組みがあります。
この記事では、doctestの基本的な使い方と、失敗しやすいパターンを整理しておきます。
doctestとは?
doctestは、関数の docstring に書いた実行例(Pythonの対話モードのような書き方)をそのままテストコードとして扱うことができる仕組みです。
実際の出力と記載された出力が一致していればテスト成功、一致しなければ失敗となります。
基本の書き方
関数に以下のように docstring として例を書きます。
def add(a, b):
"""
2つの数値を加算する関数。
>>> add(2, 3)
5
>>> add(-1, 1)
0
"""
return a + b
この >>> の行は入力を表し、その下の行は「その入力に対する戻り値」として期待する出力を書きます。
この「出力」は print() の出力ではなく、関数の戻り値がそのまま比較されます。
doctestの実行方法
doctestを実行するには、モジュールとして直接呼び出す方法があります。
if __name__ == "__main__":
import doctest
doctest.testmod()
上記のように書いておけば、ファイルを直接実行することで docstring 内のテストが自動で実行されます。
実行例(成功パターン)
def divide(a, b):
"""
aをbで割る関数。
>>> divide(6, 2)
3.0
>>> divide(5, 2)
2.5
"""
return a / b
if __name__ == "__main__":
import doctest
doctest.testmod()
このスクリプトを保存して python ファイル名.py を実行すると、すべてのテストが成功していれば何も表示されません。
失敗する例とエラーメッセージ
doctestは戻り値を文字列として厳密に比較します。
そのため、データ型や表記が異なるだけでもテストが失敗します。
例1:戻り値が文字列だと失敗する
def add(a, b):
"""
>>> add(2, 3)
5
"""
return str(a + b)
この関数は "5"(文字列)を返すため、数値 5 と一致せず失敗します。
実行結果(エラーメッセージ例)
**********************************************************************
File "sample.py", line 3, in __main__.add
Failed example:
add(2, 3)
Expected:
5
Got:
'5'
**********************************************************************
1 items had failures:
1 of 1 in __main__.add
***Test Failed*** 1 failures.
→ Expected: 5(期待値)と Got: '5'(実際の戻り値)が違うため、テストが失敗しています。
例2:出力の表記揺れで失敗する
def divide(a, b):
"""
>>> divide(3, 1)
3
"""
return a / b # 実際の戻り値は 3.0(float)
3(int)と 3.0(float)は違うものとして扱われるため、これも失敗になります。
実行結果(エラーメッセージ例)
**********************************************************************
File "sample.py", line 3, in __main__.divide
Failed example:
divide(3, 1)
Expected:
3
Got:
3.0
**********************************************************************
1 items had failures:
1 of 1 in __main__.divide
***Test Failed*** 1 failures.
→ 表記が異なるだけで失敗してしまいます。
修正したバージョン
def divide(a, b):
"""
>>> divide(3, 1)
3.0
"""
return a / b
こうすれば一致して成功します。
よくある注意点
-
>>>の行はインデントなしで書く - 出力は
print()の結果ではなく、戻り値(return)をそのまま書く - 型や表記の違いに注意(例:
5と'5'は異なる) - リストや辞書などの複雑な型は、
repr()表記で正確に書くとよい
まとめ
doctestは、関数の使い方をそのままテストとして書ける便利なツールです。
簡単な関数や学習用コードの確認に向いており、書きながら動作確認もできる点が特徴です。