python の doctest
26.3. doctest — 対話的な実行例をテストする — Python 3.5.1 ドキュメント
そういえば使ったことがなかったので触ってみたのと、使い道とかの個人的な感想メモ。
pythonでテストするときはunittest, pytest, pylintあたりしか使ったことがなかった。
demo.py
""" >>> test("omega") 'Hello, omega!' """ def test(name): return "Hello, {}!".format(name) if __name__ == "__main__": import doctest doctest.testmod()
実行結果
~$ python demo.py -v # -vすると実行詳細がみれる """ >>> test("omega") 'Hello, omega!' """ def test(name): return "Hello, {}!".format(name) if __name__ == "__main__": import doctest doctest.testmod() OMEGA:~$ python test.py OMEGA:~$ python test.py -v Trying: test("omega") Expecting: 'Hello, omega!' ok 1 items had no tests: __main__.test 1 items passed all tests: 1 tests in __main__ 1 tests in 2 items. 1 passed and 0 failed. Test passed.
こんな感じ。
ちなみにdocstringの気分で書いて、Expectingにシングルクォートで囲まないHello, omega!を記述していたら見事にfailedになった。
上記ではdemo,pyでdoctestをimportしてるけど、コマンドラインからdemo,pyを単体モジュールとしてimportしてテスト実行することもできる。
~$ python -m doctest -v demo.py
テストしたい内容が増えたりするとpythonファイルが肥大化するので、そういうときは testmod()の代わりにtestfile()と使うとよい。
doctest.testfile("test_list.txt") と書いてtest_list.txtの中にTrying/Expectingをガシガシ書いていけばいい。
test_list.txtの中身はこんな感じ。
>>> from demo import test >>> test("omega") 'Hello, omega!'
なおこれもコマンドラインから実行できる。
~$ python -m doctest -v test_list.txt
例外について思ったところ
例外については公式ドキュメントにも書いてあった。
トレースバックを貼ればいいだけらしいけど、filepathとか変更されやすいものだったりrandom的なもので毎回値が変化するようなものには向いていない。
そもそもあまり例外でテストするのは良くないと思うけど。
例外に関して評価される部分としては、例外の型からそれ以降だけらしい。
以下の場合、最初の二行はスルーされる。
Traceback (most recent call last): ... ValueError: multi line detail
やっぱり例外を扱うのはよろしくないと思う。なってほしい結果の一例としてのwikiのようなものくらいのほうが良いと思う。
感想
doctestはexampleとして記述しておくのが良いのかなと思った。私の中では今のところ、docstringをより良いものにするためのという位置付け。
あと、モジュールの方針・本当に実現したい機能を思い出させてくれるものとしても良いかも。
ガシガシコード書いてると、よく方向性見失ったりするので、、