Python
 Computer >> コンピューター >  >> プログラミング >> Python

【Python入門】doctestモジュールを使ったテストの書き方と実行方法

Pythonではdocstring(ドキュメンテーション文字列)を使うことで、関数やクラスに関する補足情報を記述できます。実はこのdocstringは、doctestモジュールによる関数のテストにも活用できます。doctestモジュールは、docstring内の「>>>」で始まるコードを自動的に実行し、その結果を期待される出力と照合してくれる便利なツールです。

doctestを使った関数の作成手順

以下の手順に従って、doctest対応の関数を作成しましょう。

  • doctestモジュールをインポートします。

  • docstring付きの関数を定義します。docstringの中に、同じ関数をテストするための次の2行を記述します。

    • >>> 関数名(*引数)

    • 期待される出力

  • 関数本体のコードを記述します。

  • 最後に、doctest.testmod(name=関数名, verbose=True) を呼び出してテストを実行します。verbose を False にすると、すべてのテストが成功した場合に結果が表示されません。テスト結果を確認したい場合は True に設定するのがおすすめです。

例1:テストが成功するケース

まずは、シンプルな関数をdoctest付きで書いてみましょう。

# モジュールのインポート
import doctest

# 関数の定義
def numbers_sum(*args) -> int:
    """
    引数すべての合計値を返す関数
    テスト用のシェルコマンド
    関数呼び出しと期待される出力:
    >>> numbers_sum(1, 2, 3, 4, 5)
    15
    >>> numbers_sum(6, 7, 8)
    21
    """
    return sum(args)

# testmod関数を呼び出してテストを実行
doctest.testmod(name='numbers_sum', verbose=True)

上記のコードを実行すると、次のような結果が出力されます。

Trying:
numbers_sum(1, 2, 3, 4, 5)
Expecting:
15
ok
Trying:
numbers_sum(6, 7, 8)
Expecting:
21
ok
1 items had no tests:
numbers_sum
1 items passed all tests:
2 tests in numbers_sum.numbers_sum
2 tests in 2 items.
2 passed and 0 failed.
Test passed.
TestResults(failed=0, attempted=2)

出力を見ると、各テストの後に「ok」という文字が表示されています。これは、期待される出力と実際の出力が一致したことを意味します。出力の最後には、テスト全体のサマリーも表示されるので、結果をひと目で確認できます。

例2:テストが失敗するケース

次に、テストが失敗するとどうなるかを見てみましょう。先ほどの例を、意図的に誤った期待値で実行してみます。

# モジュールのインポート
import doctest

# 関数の定義
def numbers_sum(*args) -> int:
    """
    引数すべての合計値を返す関数
    テスト用のシェルコマンド
    関数呼び出しと期待される出力:
    >>> numbers_sum(1, 2, 3, 4, 5)
    10
    >>> numbers_sum(6, 7, 8)
    23
    """
    return sum(args)

# testmod関数を呼び出してテストを実行
doctest.testmod(name='numbers_sum', verbose=True)

出力結果

上記のプログラムを実行すると、次のような結果が出力されます。

Trying:
    numbers_sum(1, 2, 3, 4, 5)
Expecting:
    10
**********************************************************************
File "__main__", line 10, in numbers_sum.numbers_sum
Failed example:
    numbers_sum(1, 2, 3, 4, 5)
Expected:
    10
Got:
    15
Trying:
    numbers_sum(6, 7, 8)
Expecting:
    23
**********************************************************************
File "__main__", line 12, in numbers_sum.numbers_sum
Failed example:
    numbers_sum(6, 7, 8)
Expected:
    23
Got:
    21
1 items had no tests:
    numbers_sum
**********************************************************************
1 items had failures:
    2 of 2 in numbers_sum.numbers_sum
2 tests in 2 items.
0 passed and 2 failed.
***Test Failed*** 2 failures.
TestResults(failed=2, attempted=2)

テスト結果を見ると、2件が失敗しています。失敗時の出力には、期待される出力(Expected)実際の出力(Got)が併せて表示されるため、どの部分が異なっているのかを簡単に特定できます。

補足:コマンドラインから実行する方法

スクリプト内で testmod() を呼び出さなくても、ターミナルから python -m doctest ファイル名.py -v のように実行すれば、同様にテストを行えます。-v オプションを付けると、詳細なテスト結果が表示されます。

まとめ

doctestモジュールを使えば、docstringにテストケースを直接書き込めるため、ドキュメントとテストを一元管理できるのが大きな魅力です。小規模な関数の動作確認やリグレッションテストなどに、ぜひ活用してみてください。本チュートリアルについて不明な点がある場合は、コメント欄でお気軽にお知らせください。

  1. Pythonのunittestモジュールで学ぶユニットテストの基本

    この記事では、Python 3.x(およびそれ以前のバージョン)に標準搭載されているunittestモジュールを使って、ソフトウェアテストの基礎を学んでいきます。unittestを利用すると、テストの自動化、セットアップ用コードと終了用コードの共有、そして各フレームワークに依存しない独立したテストの作成が可能になります。ユニットテストでは、オブジェクト指向プログラミングのさまざまな概念が活用されます。ここでは、特によく使われる主要な概念について解説します。TestCase(テストケース):特定の入力に対する応答を検証するための基底クラスです。unittestの基底クラス「TestCase」を継

  2. Pythonのissubset()関数とは?部分集合の判定方法を実例付きで解説

    本記事では、Python標準ライブラリに用意されているissubset()関数の仕組みと使い方について詳しく解説します。 issubset()メソッドは、あるセット(集合)のすべての要素が、引数として渡した別のセットにも含まれている場合にブール値のTrueを返し、1つでも含まれていない要素があればFalseを返します。 下の図では、BはAの部分集合です。もしAとBが同一のセットであれば、両者は互いに部分集合の関係にあるといえます。つまり、両方のセットがまったく同じ要素を持っているということを意味します。 構文 <set 1>.issubset(<set 2>) 戻り値