doctestを使ってPythonでテストを書く方法
Mannan Tirmizi
2022年11月21日
0 分で読めます開発者は、コードを説明するためにテストケースやコメントをよく書きます。コメントを付けることで、コードベースの読みやすさと品質が向上します。詳しいコメントがあれば、特定の機能を実装した理由を思い出すのにも役立ちます。また、ほかのプログラマーがコードベースを理解し、保守、活用、拡張する助けにもなります。
ベストプラクティスの一つは、関数のコメントとテストケースを先に書くことです。そうすることで、関数のさまざまな境界ケースや要件を意識しながら、より高品質なコードを書けます。しかし、従来の方法は非常に時間がかかります。テストごとに別のケースファイルを用意し、長い関数を書く必要があるためです。
このような場合に非常に便利なのが、Pythonのdoctestツールです。オープンソースコミュニティが、開発向けの効率的なテストフレームワークとしてdoctestモジュールを開発しました。入力値と出力値の両方を定義すれば、関数内のコードのテストをdoctestで記述できます。これにより、時間と労力を節約しながら、質の高いコードを書けます。
便利そうですが、Pythonでdoctestを書くには具体的にどうすればよいのでしょうか?この記事では、最初のdoctestをセットアップし、作成してテストするまでの手順を解説します。始めるために必要な情報をすべてご紹介します。
最初のdoctestを書く方法
最初のPython doctestを書く前に、パソコンにPython 3と、Visual Studio Code(VS Code)などの適切な開発環境がインストールされていることを確認してください。この記事では、統合開発環境(IDE)としてVS Codeを使用します。
IDEをセットアップする
Python 3をインストールしたら、インストールが正常に完了したことを確認します。Windowsの場合は、コマンドプロンプトで次のコードを入力します。
macOSまたはUnixの場合は、ターミナルを起動して次のコマンドを入力します。
次に、IDEのVisual Studio Codeをダウンロードします。
セットアップウィザードを起動し、画面の指示に従ってVS Codeをインストールします。
VS Codeを起動したら、ExtensionsタブからPython extensionをダウンロードします。これで、VS CodeでPythonを使う準備が整いました。
docstringの紹介
Pythonにはdocstringという仕組みがあります。docstringは文字列リテラルで、関数、クラス、またはモジュールの宣言内に記述し、関数のコメントやテストケースとして使います。そのため、docstringはドキュメント作成とテストの両方に欠かせません。
docstringは、三重引用符で囲んで記述できます。
docstringの後に、コメントとテストをどちらも三重引用符で囲んで記述できます。
このチュートリアルでは、テストケースとコメントの構文を学びます。一見すると、docstringとコメントは似ているように思えるかもしれません。しかし、役割は異なります。コメントはコードの実装を説明するものですが、docstringはクラス、メソッド、関数を説明するものです。関数の目的や、業務での使い方をほかのプログラマーが理解するのに役立ちます。
doctestモジュールは、関数またはクラス定義内にあるdocstringを見つけて、その役割を判断します。docstring内のテストケースの先頭に>>>記号を付けることで、コメントとテストコードを識別し、区別します。
お使いのOSでコマンドラインを開き、python3と入力します。

Python 3の対話型シェルでは、プロンプトに>>>記号が使われ、出力にはこの記号が含まれません。値を出力すると、対話セッションは次のようになります。

doctestモジュールは、対話型Pythonセッションのように見えるパターンをdocstring内から探して検出します。検出すると、その内容を実行します。doctestは、関数呼び出しまたはメソッドのヘッダーの直後にある最初のdocstring内に記述する必要があります。予期しないエラーや失敗を避けるため、doctestを記述した後に余分なスペースを入れないようにしてください。
doctestを書く
doctestを使うために、まずサンプルコードを書いてみましょう。このチュートリアルでは、square.pyという基本的なモジュールを作成し、squareという関数を定義します。この関数は、与えられた入力値の二乗を求めます。
次に、関数内にdocstringを追加します。このdocstringには、関数の動作を説明するドキュメントを記述します。また、入力値と期待される出力値を含む2つのテストケースも記述します。関数の処理結果をテストする際に、これらの値が使われます。
処理結果はどのようにテストされるのでしょうか?
doctestモジュールはdocstringを解析してテキストを生成し、そのテキストをPythonシェルのコマンドとして実行します。その後、実行結果とdocstringに記述された期待値を比較します。
doctestを実行する方法
モジュールsquare.pyでdoctestを実行するには、doctestのtestmod関数を追加します。doctest.testmod関数は、モジュールmをテストします。mが指定されていない場合は、モジュール"_main_"をテストします。この関数はdoctestの実行に必要です。
次に、ターミナルで次のコマンドを使ってsquare.pyモジュールを実行します。
square.pyには関数が1つしかないため、doctestモジュールはその関数だけをテストします。

何も出力されない場合は、すべてのテストに合格しています。テストに失敗すると、エラーがターミナルに表示されるので、適宜対処できます。ログを表示するには、スクリプトに-vを追加します。

ログには、テストの成功率と失敗率が表示され、結果をより詳しく確認できます。また、便利な方法として、main関数を使わずにtestmod関数を実行することもできます。doctestモジュールは標準ライブラリに含まれているため、直接実行できます。その場合は、コマンドラインインターフェースにモジュール名を渡します。
では、先ほどの例を少しだけ拡張してみましょう。関数の入力データと出力データの型を指定したい場合はどうすればよいでしょうか?docstringを少し変更するだけで指定できます。先ほどの例に、次の内容を追加します。
すると、docstringは次のようになります。
入力パラメーターが複数ある場合は、:paramを変更できます。入力パラメーターが2つある場合、該当するdocstringは次のようになります。
必要な数だけ入力パラメーターを追加できます。
おめでとうございます!これでdoctestを書けました。
まとめ
この記事では、Pythonのdoctestモジュールの基本を紹介し、doctestによってコードの品質を高め、より優れた開発手法を実現できることを説明しました。
また、関数にdoctestを組み込み、コードファイルとターミナルを使って実行する方法を紹介し、コーディングでdoctestモジュールを簡単に使えることを示しました。
従来の関数テストでは、テストケースを含む独立したスクリプトを作成します。doctestを使えば、そのようなスクリプトを書く必要がなくなり、より効率的にコードをテストできます。つまり、テストの煩わしさを軽減し、Pythonコードの品質を向上させることができます。
Capture the Flagを始めよう
オンデマンドのバーチャル入門ワークショップを見て、Capture the Flagの課題の解き方を学びましょう。