Cou氏の徒然日記

ほのぼの日記ブログです。

Python3の学習 その19 (doctest:テスト)

Python

今回はdoctestについて。

テスト駆動型開発をするうえで、テストコードも必ずセットで書くことが多いですが、その中の一つのやり方が、doctestモジュールを使うことのようです。

 

■ doctestモジュール

例えば、下記のような足し算、引き算の結果を返す関数を定義します。

def sum(a, b):
    return a + b

def sub(a, b):
    return a - b

 

上記の関数のテストとして、以下のようなものを記載。

"""
テストを記載
>>> sum(0, 1)
1
>>> sum(-2, 5)
3
>>> sub(5, 3)
2
>>> sub(2, 7)
-5

テスト内容は以上
"""

def sum(a, b):
    return a + b

def sub(a, b):
    return a - b

import doctest
doctest.testmod()

 

「>>>」で「関数の呼び出し処理」を記載し、次の行に「戻り値の期待値」を記載すればOKのようです。

そして、テストを実行するために、doctest.testmod() 関数が実行されるように書くだけ。

 

この状態で実行すると…

coublood@penguin:~/python$ python3 doctest1.py -v
Trying:
    sum(0, 1)
Expecting:
    1
ok
Trying:
    sum(-2, 5)
Expecting:
    3
ok
Trying:
    sub(5, 3)
Expecting:
    2
ok
Trying:
    sub(2, 7)
Expecting:
    -5
ok
2 items had no tests:
    __main__.sub
    __main__.sum
1 items passed all tests:
   4 tests in __main__
4 tests in 3 items.
4 passed and 0 failed.
Test passed.

テストの実行結果が表示されます。

上記だと、記載したテストは4件ともpassできているので、期待通りに関数が動いていると判断できるということですね。

 

ちなみに、doctest.testmod()の実行処理を入れたくない場合は、python実行時にオプション(-m doctest)を追加することで、テスト実行をできるようです。

coublood@penguin:~/python$ python3 -m doctest -v doctest2.py 
Trying:
    sum(0, 1)
Expecting:
    1
ok
Trying:
    sum(-2, 5)
Expecting:
    3
ok
Trying:
    sub(5, 3)
Expecting:
    2
ok
Trying:
    sub(2, 7)
Expecting:
    -5
ok
2 items had no tests:
    doctest2.sub
    doctest2.sum
1 items passed all tests:
   4 tests in doctest2
4 tests in 3 items.
4 passed and 0 failed.
Test passed.

これなら部分的にテストを流すことも簡単ですね。

 

■ 外部ファイルにテストを記載して実行

テストを外部ファイルに記載して、そのテストだけを実行することも可能のようです。

  • doctest2.py:関数定義
  • test_doctest2.txt:テストを記載
  • test_doctest2.py:test_doctest2.txtのテストを実行
coublood@penguin:~/python$ cat test_doctest2.txt
>>> from doctest2 import sum
>>> from doctest2 import sub

>>> sum(2, 5)
4
>>> sub(2, 5)
-3
coublood@penguin:~/python$ cat test_doctest2.py
import doctest
doctest.testfile("test_doctest2.txt")

coublood@penguin:~/python$ python3 test_doctest2.py 
**********************************************************************
File "/home/coublood/python/test_doctest2.txt", line 4, in test_doctest2.txt
Failed example:
    sum(2, 5)
Expected:
    4
Got:
    7
**********************************************************************
1 items had failures:
   1 of   4 in test_doctest2.txt
***Test Failed*** 1 failures.

ただし、テストが全件正常だと何も表示されないので、イマイチ正しく実行されているのかわからなかったので、「あれっ?」と思ったのですが…

あえて間違ったテストを設定して実行すると表示されたので、正しく実行されているかどうかは(動作しているかは)、間違ったテストを一度入れないと判別がつかなさそうですね。