python docstring内にテストを記述

`doctest`モジュールの`doctest.testmod()`関数はdocstring内にテストを記述し、verboseモードで実行することでテストが実行される

# 今まではこう書いてたところ

```python:sample.py
def twice(n):
    """ 引数を 2 倍して返す関数
    >>> twice(8)
    16
    >>> twice(1850923)
    """
    return n * 2


'''TEST
twice(8)
 # 実行結果
 #16
twice(1850923)
 # 実行結果
 #3701846
'''# ←ここのトリプルクォートを'TEST'って書いてあるところまで引き上げてやることでtwice(8), twice(1850923)を実行する
```

`TEST`下のトリプルクォートを`TEST`のところまで上げてやるとdocstring的な複数行コメントアウトが外れ、実行したときに`twice`関数が実行されてテストされる。
その`TEST`ってやつは関数より下にあるから、見た目が悪い。
できることならdocstringにまとめたい。









# doctestモジュールを使う

しかしdoctestモジュールを使えばdocstring内に記述できて、他のモジュールから実行したときに実行させない、器用なことができる

```python:doctest_sample.py
def twice(n):
    """ 引数を 2 倍して返す関数
    >>> twice(8)
    16
    >>> twice(1850923)
    3701846
    """
    return n * 2


print('name?>>', __name__)
if __name__ == "__main__":
    doctest.testmod()

print('EOF')

```









# 実行結果を以下の4つの方法で検証

1. ipython
    1. `%run doctest_sample -v`
    1. `%run doctest_use.py -v`
2. sublimetext
    2. sublimetext上でdoctest_sample.pyを実行
    2. sublimetext上でdoctest_use.py.pyを実行
    > doctest_use.py.pyの内容はimportを行うだけ
    >>```python:doctest_sample.use.py
    import doctest_sample
    ```


ipython上でpythonファイルを実行するときは'%run <filename>'でrunする。
`doctest.testmod()`を使うときはverboseモード`-v`で実行する。

sublimetext上で実行するときは`ctrl+b`でbuildする。
verboseモードの実行はデフォルトでは入ってない(嘘か本当か未検証)のでbuildシステムを作ってUserディレクトリに保存
メニュー>ツール>Buile systemから作成した`Python_Verbose`を選択して`ctrl+b`

```JSON:Python_Verbose.sublime-build
{
    "cmd": ["python", "$file", "-v"],
    "file_regex": "^[ ]*File \"(...*?)\", line ([0-9]*)",
    "selector": "source.python"
}
```


### コマンドライオプション-uと-vについて

1 コマンドラインと環境(http://docs.python.jp/3.3/using/cmdline.html)
1.1 コマンドライン
1.1.3 その他のオプション

-u¶(原文)

Force the binary layer of the stdout and stderr streams (which is available as their buffer attribute) to be unbuffered. The text I/O layer will still be line-buffered if writing to the console, or block-buffered if redirected to a non-interactive file.

PYTHONUNBUFFERED も参照してください。

-v

モジュールが初期化されるたびに、それがどこ(ファイル名やビルトインモジュール) からロードされたのかを示すメッセージを表示します。 2重に指定された場合(-vv)は、モジュールを検索するときにチェックされた各ファイルに対してメッセージを表示します。また、終了時のモジュールクリーンアップに関する情報も提供します。 PYTHONVERBOSE も参照してください。





## 結果1.1 ipython上で`%run doctest_sample -v`

```pycon:1.1
In [80]: run doctest_sample.py -v
name?>> __main__
Trying:
    twice(8)
Expecting:
    16
ok
Trying:
    twice(1850923)
Expecting:
    3701846
ok
1 items had no tests:
    __main__
1 items passed all tests:
   2 tests in __main__.twice
2 tests in 2 items.
2 passed and 0 failed.
Test passed.
EOF
```

name属性がmainなので、doctestが実行される
doctestの記述は
`>>>`で書いたところでpython形式で実行し、結果を返す
エラーがなければ`ok`と出して次のテストに進む。

```pycon:1.1
Trying:
    twice(8)
Expecting:
    16
ok
```

テストサマリーを表示する

```pycon:1.1
1 items had no tests:
    __main__
1 items passed all tests:
   2 tests in __main__.twice
2 tests in 2 items.
2 passed and 0 failed.
Test passed.
body...
```




## 結果1.2 ipython上で`%run doctest_use -v`


```pycon:1.2
In [81]: run doctest_use.py

```

出力が何も表示されない。



## 結果2.1 sublimetext上でdoctest_sample.pyをbuild

```pycon:2.1
name?>> __main__
Trying:
    twice(8)
Expecting:
    16
ok
Trying:
    twice(1850923)
Expecting:
    3701846
ok
1 items had no tests:
    __main__
1 items passed all tests:
   2 tests in __main__.twice
2 tests in 2 items.
2 passed and 0 failed.
Test passed.
EOF
[Finished in 0.5s]
```

sublimetextのビルド結果に表れる`[Finished in 0.5s]`以外1.1の結果と同じ



## 結果2.2 sublimetext上でdoctest_use.pyをbuild

```pycon:2.2
name?>> doctest_sample
EOF
[Finished in 0.4s]
```

結果1.2と異なりprint文は実行されるようだ。





# まとめ

* docstring内にテストを記述する
* `docstring.testmod()`を記述する
    * name属性がmainの時に実行するようif文の中に入れておく(doc.py参照)
* pythonをverboseモードで実行する(`python <filename> -v`)

```python:doc.py
import docstring

def hoge():
    '''
    hoge(args)
    '''


if __name__ == "__main__":
    doctest.testmod()
```





## 参考
[Python でテスト](http://qiita.com/phimcall/items/7378ec86fbabdca83257)
[コマンドラインと環境](http://docs.python.jp/3.3/using/cmdline.html)