tachitomonn’s blog

IT技術関連の学習メモがメインでたまに趣味のこととか

Python でお手軽テスト doctest

公式ドキュメントを参考に doctest のお勉強。
doctest --- 対話的な実行例をテストする — Python 3.8.1 ドキュメント

doctest モジュールは、対話的 Python セッションのように見えるテキストを探し出し、セッションの内容を実行して、そこに書かれている通りに振舞うかを調べます。

平成暦を西暦に変換する関数(単に試しの例が他に思いつかなかっただけで特に意味なし)を書いて試してみた。

study_doctest.py

#! /usr/bin/env python

u"""doctest の勉強用サンプル
"""

def heisei2seireki(n):
    u"""平成暦を西暦に変換
    >>> [heisei2seireki(n) for n in range(1, 32)]
    [1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019]
    >>> heisei2seireki(-1)
    Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
        File "c:\selfstudy\study_doctest.py", line 12, in heisei2seireki
        raise ValueError(u"n は1以上!")
    ValueError: n は1以上!
    >>> heisei2seireki(0)
    Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
        File "c:\selfstudy\study_doctest.py", line 12, in heisei2seireki
        raise ValueError(u"n は1以上!")
    ValueError: n は1以上!
    >>> heisei2seireki(1.5)
    Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
        File "c:\selfstudy\study_doctest.py", line 14, in heisei2seireki
        raise ValueError(u"n は整数!")
    ValueError: n は整数!
    >>> heisei2seireki(32)
    Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
        File "c:\selfstudy\study_doctest.py", line 16, in heisei2seireki
        raise ValueError(u"n の最大値は31!")
    ValueError: n の最大値は31!
    """

    import math
    if not n > 0:
        raise ValueError(u"n は1以上!")
    if math.floor(n) != n:
        raise ValueError(u"n は整数!")
    if n > 31:
        raise ValueError(u"n の最大値は31!")
    result = n + 1988
    return result

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

このスクリプトコマンドラインから実行すると出力は何もないが、すべての実行例が正しく動作しているからとのこと。
-v オプションを付けて実行すると何を実行しようとしたかを記録したログを出力し、最後にまとめを出力してくれる。

>python study_doctest.py -v
Trying:
    [heisei2seireki(n) for n in range(1, 32)]
Expecting:
    [1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019]
ok
Trying:
    heisei2seireki(-1)
Expecting:
    Traceback (most recent call last):
        File "", line 1, in 
        File "c:\selfstudy\study_doctest.py", line 12, in heisei2seireki
        raise ValueError(u"n は1以上!")
    ValueError: n は1以上!
ok
Trying:
    heisei2seireki(0)
Expecting:
    Traceback (most recent call last):
        File "", line 1, in 
        File "c:\selfstudy\study_doctest.py", line 12, in heisei2seireki
        raise ValueError(u"n は1以上!")
    ValueError: n は1以上!
ok
Trying:
    heisei2seireki(1.5)
Expecting:
    Traceback (most recent call last):
        File "", line 1, in 
        File "c:\selfstudy\study_doctest.py", line 14, in heisei2seireki
        raise ValueError(u"n は整数!")
    ValueError: n は整数!
ok
Trying:
    heisei2seireki(32)
Expecting:
    Traceback (most recent call last):
        File "", line 1, in 
        File "c:\selfstudy\study_doctest.py", line 16, in heisei2seireki
        raise ValueError(u"n の最大値は31!")
    ValueError: n の最大値は31!
ok
1 items had no tests:
    __main__
1 items passed all tests:
   5 tests in __main__.heisei2seireki
5 tests in 2 items.
5 passed and 0 failed.
Test passed.

個人の趣味の範囲での開発におけるテストならこれでも良いかも。