私が無視しているテスト機能-doctestモジュール

5484 ワード

前言


以前は簡単にチュートリアルに従ってdoctestモジュールを1回打ったことがありますが、重視していません.それに、自分が普段テストケースを使わないので、最近本でこのモジュールを見たとき、心がぼんやりしていました.そこで今回は、doctestモジュールについて、unittestについて少し言及します.

なぜ無視したの?


くだらないことを言わないで、私の日常的な操作(ほとんどの人の操作かもしれません)を直接見て原因を得ることができます.
""" Fibonacci Module """

def fib(n):
    """ Calculates the n-th Fibonacci number iteratively """
    a, b = 0, 1
    for i in range(n):
        a, b = b, a + b
    return a

def fiblist(n):
    """ creates a list of Fibonacci numbers up to the n-th generation """
    fib = [0,1]
    for i in range(1,n):
        fib += [fib[-1]+fib[-2]]
    return fib

上はフィボナッチ数列の日常的な実現です.私たちはいつもこのようにしています(手動テスト)、ここで手動で斜め目です.
>>> from fibonacci import fib, fiblist
>>> fib(0)
0
>>> fib(1)
1
>>> fib(10)
55
>>> fiblist(10)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
>>> fiblist(-8)
[0, 1]
>>> fib(-1)
0
>>> fib(0.5)
Traceback (most recent call last):
  File "", line 1, in 
  File "fibonacci.py", line 6, in fib
    for i in range(n):
TypeError: 'float' object cannot be interpreted as an integer
>>> 

感覚で思いついたことを知って、浮動小数点数を入力すると間違いを報告します.ファイルに次のコードを追加するなど、簡単な判断テストを書きます.
if __name__ == "__main__":
    if fib(0) == 0 and fib(10) == 55 and fib(50) == 12586269025:
        print("Test for the fib function was successful!")
    else:
        print("The fib function is returning wrong values!")

#  
$ python3 fibonacci.py 
Test for the fib function was successful!

関数が事前に計算した値を得られなかった場合は、"The fib function is returning wrong values!を返します.
だから結論は:doctestはあまり使えないようですね.私たちは上のようにすれば十分です.

doctestモジュール


どのような場合にdoctest:正式なプロジェクトのテストを使うか、優雅な方法で、格を高くするテストケースが必要です.一般的に以下の要素がある場合は、できるだけ試してみてください.
  • サイズ対集合(string,list,tuple,dict)
  • 空集合
  • 単一要素セット
  • 最少数用例
  • 多用例
  • 対分
  • 奇数/偶数
  • 正/負
  • 空/満
  • 境界関数は閾値に近づくと処理が異なり、閾値をテストする.
  • シーケンス関数は、異なるシーケンスの入力値に対して、異なるシーケンスをテストする.

  • だから私たちはこう書くことができます
    import doctest
    
    def fib(n):
        """ 
        Calculates the n-th Fibonacci number iteratively  
    
        >>> fib(0)
        0
        >>> fib(1)
        1
        >>> fib(10) # 55
        56            
        >>> fib(15)
        610
        >>> 
    
        """
        a, b = 0, 1
        for i in range(n):
            a, b = b, a + b
        return a
    
    if __name__ == "__main__": 
        doctest.testmod(verbose=True)
    

    その後、$ python3 fibonacci_doctest.pyによって試験情報が得られ、verbose=Trueによって試験合格と不合格の両方についてメッセージが表示され、デフォルトではFalseであり、失敗情報のみが表示される.
    Trying:
        fib(0)
    Expecting:
        0
    ok
    Trying:
        fib(1)
    Expecting:
        1
    ok
    Trying:
        fib(10) 
    Expecting:
        56
    **********************************************************************
    File "fibonacci_doctest.py", line 11, in __main__.fib
    Failed example:
        fib(10) 
    Expected:
        56
    Got:
        55
    Trying:
        fib(15)
    Expecting:
        610
    ok
    1 items had no tests:
        __main__
    **********************************************************************
    1 items had failures:
       1 of   4 in __main__.fib
    4 tests in 2 items.
    3 passed and 1 failed.
    ***Test Failed*** 1 failures.
    
    if __name__ == "__main__":の下にテスト関数ではなく他の関数を書く必要がある場合もあります.方法を変えてもいいです.メイン関数を変更します.
    if __name__ == "__main__":
        print('hello world')
    

    その後、$ python3 -m doctest -v fibonacci_doctest.pyは、上記のテスト情報と同様に、hello worldは出力されず、ここで−vはverboseパラメータに等しい.

    unittestが必要かどうか


    unittestはユニットテストフレームワークで、具体的なチュートリアルは公式ドキュメントに照会することができます.ここではあまり紹介しません.一部の人はunittestの余分なdoctestを使って、主な原因は私がテスト内容を関数の中に書いて、関数の注釈のように、いったんテストするものが多くなると、関数が複雑に見えて、美観に影響して、優雅ではありません.しかしdoctestにはtestfileの方法があり、テストドキュメントを個別のファイルに書き込む.ここに書いておきます.
    #  py , , txt 
    The ``fibonacci_doctest`` module
    ======================
    
    Using ``fib``
    -------------------
    
    First import fib fuction
    
        >>> from fibonacci_doctest import fib
    
    Now use it
        >>> fib(0)
        0
        >>> fib(1)
        1
        >>> fib(10)  # 55
        56
        >>> fib(15)
        610
    #  , ,  >>>  
    

    次に、fibonacci_doctest.pyのメイン関数に次のように書きます.
    if __name__ == "__main__":
        doctest.testfile("fibonacci_doctest.txt")
    

    次のようになります.
    **********************************************************************
    File "fibonacci_doctest.txt", line 16, in fibonacci_doctest.txt
    Failed example:
        fib(10) # 55
    Expected:
        56            
    Got:
        55
    **********************************************************************
    1 items had failures:
       1 of   5 in fibonacci_doctest.txt
    ***Test Failed*** 1 failures.
    

    OK、終わります.使いやすいです.

    まとめ

    doctestモジュールをテストするときは基礎を比較して、分かりやすくて使いやすいです.
    前に一人の大物が言ったのを見て、大体の意味はこうです:あなたは1つの関数を書き終わって、心の中ですでにテストのケース、各種のテスト要素を考えて、あなたが書いたこの関数の正確性を検証します.
    そのとおりです.

    参考資料


    https://www.python-course.eu/python3_tests.php http://blog.csdn.net/u012151283/article/details/77511806 https://docs.python.org/3/library/doctest.html#doctest.testfile