Help us understand the problem. What is going on with this article?

Pythonでユニットテスト書いてみよう-2

概要

Pythonのユニットテストについて前回はunittestを紹介しました。今回は「doctest」について紹介します。

docstring

doctestを理解するためには、docstringを理解することが重要です。関数やクラスなどの機能を簡単に分かるために、それらの定義の先頭に入れる文字列の事をdocstringと言います。docstringがある事で他のところから参照する時に、その説明を簡単に見ることができます。
説明だけではわかりにくいので実際にコードを書いて確認してみましょう。
先ず、sample.pyというファイルを作成し、以下の内容を保存してください。

def add(num1, num2):
    """
    引数として受けた数値を足し算し、
    その結果を返す。

    Parameters
    ----------
    num1 : int
        1つ目の足し算する数値
    num2 : int
        2つ目の足し算する数値

    Returns
    -------
    result : int
        足し算の結果
    """
    result = num1 + num2
    return result

ターミナルから「sample.py」保存したフォルダーに移動し、以下のコマンドを実行してください。

$ python -c "import sample;print(sample.add.__doc__)"

以下の様に表示されると思います。

    引数として受けた数値を足し算し、
    その結果を返す。

    Parameters
    ----------
    num1 : int
        1つ目の足し算する数値
    num2 : int
        2つ目の足し算する数値

    Returns
    -------
    result : int
        対足し算の結果

上で表示されたように関数やクラスの説明を後で簡単に確認ができます。別ファイルから関数やクラスを呼び出す時は便利ですね。
VS Codeではマウスポインタを対象の関数などに合わせるとツールチップにdocstringが表示されます。
ちなみに、以下のコマンドを実行しても同じ結果になります。

python -c "import sample;help(sample.add)"

doctest

doctestはdocstringを使ってユニットテストを実装するモジュールです。docstringの中に入出力例を書いてテストを実装します。unittestと同様にPythonをインストールした時点で利用可能になっているので、第三者のライブラリをインストールする必要がありません。Pythonの環境さえあれば、簡単に検証ができます。
docstring(コメント)にテストケースを書いて、それ以外は実際に動かすコードを書きます。

基本的にdoctestは、以下の順に書きます
1. doctestライブラリをインポートする
2. docstringの末尾にテストケースを記述
3. doctest.testmod()でテストを実行する

# 1. doctestのインポート
import doctest

# 2. docstringの末尾にテストケースを記述
def func_xxx():
    """
    関数の説明
    テストケース記述
    """
    関数の中身

if __name__ == '__main__':
    # 3. 実行
    doctest.testmod()

doctest書き方

「sample.py」の中身を上記で書いて順に沿って、以下のように変えます。

import doctest

def add(num1, num2):
    """
    引数として受けた数値を足し算し、
    その結果を返す。

    Parameters
    ----------
    num1 : int
        1つ目の足し算する数値
    num2 : int
        2つ目の足し算する数値

    Returns
    -------
    result : int
        対足し算の結果

    UnitTesting
    -------
    >>> add(2, 3)
    6
    """
    result = num1 + num2
    return result

if __name__ == '__main__':
    doctest.testmod()

お気付きだと思いますが、docstring(コメント)の最後の2行がテストケースになります。2と3足したら5になりますが、あえて6が期待値として書いております。
このようにソースコードの中にテストケースも一緒に残るので後で見てもわかりやすいですね。

python sample.pyを実行するだけでテストが開始されます。

$ python sample.py
**********************************************************************
File "sample.py", line 22, in __main__.add
Failed example:
    add(2, 3)
Expected:
    6
Got:
    5
**********************************************************************
1 items had failures:
   1 of   1 in __main__.add
***Test Failed*** 1 failures.

もしテストケースが全て正しかった場合は、上記のコマンドを実行したら何も出力されません。何も出力しないと何が起きたかわからないため、わざと結果が6と書いておき、テストを失敗させました。ちなみに、python sample.py -vを実行するとどのように検証行ったか詳細に表示されます。

補足

上記の手順の①と③をソースコードに書かずにテスト実装する事もできます。以下の内容を「sample2.py」として保存してください。

def add(num1, num2):
    '''
    足し算
    >>> add(2, 3)
    6
    >>> add(-2, 3)
    1
    '''
    return num1 + num2

ターミナルからpython -m doctest sample2.pyを実行するだけでユニットテストが開始されます。

$ python -m doctest sample2.py
**********************************************************************
File "C:\Users\dakc\sample2.py", line 4, in sample2.add
Failed example:
    add(2, 3)
Expected:
    6
Got:
    5
**********************************************************************
1 items had failures:
   1 of   2 in sample2.add
***Test Failed*** 1 failures.

出力内容通り、2つのテストケースの中で一つが失敗した事が分かります。
テストケースを色々書いてどのような結果が得られるか見てみて下さい。

最後に

前回は、unittestを紹介しました。
こちらで、pytestについて書いております。
doctestとの違いを比較してみてください。

_dakc_
外国人SEです。20代で管理職を経験し、今は転職して平社員です。お互い信頼しあい、お互い尊敬しあい、時には冗談できるチームを作れるように平でありながら、日々マネジメント+技術を学んでおります。 好きな言葉 ☞ Accept the challenges so that you can feel the exhilaration of victory.
https://github.com/dakc
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした