この記事では、Pythonのdocstringを使ってテストする方法を解説します。
docstringは、説明や概要を書いたりしてドキュメントを作成するためのものですが、doctestモジュールを使うことで実行例を書いてテストさせることもできます。
doctestモジュールは主に以下の目的で使われます。
- docstringが最新かチェックする
- 回帰テストする
- 書いたテストが使い方の例になる
docstringの書き方は以下の記事を参照してください。
ドキュメンテーション文字列の書き方を解説【docstring】
それでは、docstringを使ってテストする方法を見ていきましょう!
docstringでテストを行う手順
まずは、ドキュメンテーション文字列を使ってテストを行う手順を見ていきましょう。
-
STEP1対話実行例を書くドキュメンテーション文字列中に対話実行例を記述します。書き方は後述。
def func(): ''' 実行例 ''' -
STEP2doctestのチェックスクリプトが
__main__として実行されたらテストがチェックされるようにしておく。if __name__ == "__main__": import doctest doctest.testmod() -
STEP3テストするテストするにはスクリプトファイルをエントリポイントとして実行します。
$ python3 スクリプトファイルテスト結果は後述。
それでは、次に実行例の書き方を見ていきます。
対話実行例の書き方
docstring中に関数の呼び出しと期待される出力を記述します。
def div(a, b): """ >>> div(4, 2) 2.0 """ return a / b
>>>div(4, 2)が呼び出しで、その下の2.0が期待される出力です。
また、期待される出力にエラーを記述することもできます。
def div(a, b): """ >>> div(4, 2) 2.0 >>> div(0, 0) Traceback (most recent call last): ... ZeroDivisionError: division by zero """ return a / b
「こういった呼び出し方がされたらこの結果が返る」というパターンを増やしていくことでテストを強固にすることができます。
テストの成否の挙動
テストが成功する場合と失敗する場合の挙動の違いを確認していきましょう。
実行例が成功する例
実行例が正しい場合のdocstringを試してみます。
div.py
def div(a, b): """ >>> div(4, 2) 2.0 """ return a / b if __name__ == "__main__": import doctest doctest.testmod()
このコードをコマンドラインから実行します。
$ python div.py
実行例が成功すると特に何も表示されません。
実行例が失敗する例
実行例が間違っている場合のdocstringを試してみます。
div.py
def div(a, b): """ >>> div(4, 2) 2 """ return a / b if __name__ == "__main__": import doctest doctest.testmod()
このコードを実行すると以下のような出力がされます。
$ python div.py ********************************************************************** File "div.py", line 5, in __main__.div Failed example: div(4, 2) Expected: 2 Got: 2.0 ********************************************************************** 1 items had failures: 1 of 1 in __main__.div ***Test Failed*** 1 failures.
docstringに記述した期待される出力がExpectedで、実際に出力された値がGotです。
実行例ではint型の値が返ってくると記述していましたが、実際に返ってきた値はfloat型だったのでテストが失敗して予想した挙動になっていないことがわかりました。
まとめ
この記事では、docstringを使ってコードをテストする方法を解説しました。
色々なテスト方法がありますがdoctestはテストするコードと実行例が同じ場所にあるのでわかりやすい反面、関数などに直接書くことになるのでコードが長くなってしまいます!
テストが長くなってしまう場合はunittestなどを使いましょう!
それでは今回の内容はここまでです。ではまたどこかで〜( ・∀・)ノ


