matrk's blog

十中八九Python書いてる

インタラクティブモードのログとdoctest

 Pythonインタラクティブでごにょごにょしてから^Dで抜けると~/.python_historyにログ(コマンドのみ)が残ります。doctestの為にログが必要なのにうっかり流れてしまった、みたいなときに役立つかもしれません。私はまだ役立てられた事無いです。下記参照。

doctest

 ついでにdoctestの話します。私はつい最近までdoctestというとdocstringにクソ長いテストケースを書かなきゃならんものだと思っていました。  ですが実際はそんな事は無く、外部ファイルをテストドキュメントとして利用する事が可能です。実用を考えるとそちらの利用が圧倒的に多いと思います。

documentをtestに

test.mdを用意し、以下のように記述します。

# This is a cute doctest.

## The `fizzbuzz` function
First, import `fizzbuzz` function in `fizzbuzz.py`

    >>> from fizzbuzz import fizzbuzz

Now you can use `fizzbuzz` function as shown in these test cases:

    >>> for called in fizzbuzz(-1):
    ...     print(called)
    Traceback (most recent call last):
      ...
    ValueError: Negative number is not accepted in argument.
    >>> for called in fizzbuzz(0):
    ...     print(called)
    >>> for called in fizzbuzz(4):
    ...     print(called)
    1
    2
    fizz
    >>> for called in fizzbuzz(16):
    ...     print(called)
    1
    2
    fizz
    4
    buzz
    fizz
    7
    8
    fizz
    buzz
    11
    fizz
    13
    14
    fizzbuzz

 で、python -m doctest test.mdのように実行するか、インタラクティブだかファイルを用意して

import doctest
doctest.testfile("test.md")

とするとテストが書かれたドキュメントtest.mdがdoctestとして実行されます。ちなみにファイルを用意した場合、-vオプションを付けるとテストの詳細情報を表示できます。

doctestでドキュメントが素敵に

 これの何が素敵って作成されたtest.mdはそのままmarkdownとしてドキュメントになっています。というかむしろドキュメントをテストとして使えるからdoctestなわけです。ドキュメントが充実するって素敵。場合によっては(もしかすると大抵の場合)テストケースが膨大になってドキュメントとして役に立たないかもしれませんけど。

 ちなみにgithubやgitlabなんかは拡張子を.mdにしないとmarkdownとして認識してくれなかった気がします。 ということで私はdoctestを使うとき以下のような構造で書いてます。

  • module.py - コード本体
  • .module.foo.md -
  • .module.bar.md - doctest。何のテストか分かりやすい名前に。
  • testrun.py - doctest全部をまとめてテストするためのもの

 doctestについて詳細は下記参照。