0

を使用して関数のテストを作成したい関数がたくさんあるpythonファイルを想定していますdoctest。たとえば、すべての関数は文字列と接続オブジェクト ( httplib.HTTPConnection(...)) を取ります。したがって、文字列が空またはNone. テストは次のようになります。

def function_1(mystring, conn):
    r'''
    >>> conn = httplib.HTTPConnection(...)
    >>> function_1(None, conn)
    Traceback (most recent call last):
    NoneAsInputError: `mystring` should be a string and not `None`!

    >>> function_1("", conn)
    Traceback (most recent call last):
    EmptyStringError: `mystring` should not be an empty string!
    '''

    pass

def function_2(mystring, conn):
    r'''
    >>> conn = httplib.HTTPConnection(...)
    >>> function_2(None, conn)
    Traceback (most recent call last):
    NoneAsInputError: `mystring` should be a string and not `None`!

    >>> function_2("", conn)
    Traceback (most recent call last):
    EmptyStringError: `mystring` should not be an empty string!
    '''

    pass

[...]

def function_n(mystring, conn):
    r'''
    >>> conn = httplib.HTTPConnection(...)
    >>> function_n(None, conn)
    Traceback (most recent call last):
    NoneAsInputError: `mystring` should be a string and not `None`!

    >>> function_n("", conn)
    Traceback (most recent call last):
    EmptyStringError: `mystring` should not be an empty string!
    '''

    pass

ご覧のとおり、テストは同じで、関数名のみが変更されています。コードの繰り返しを避けるためにそれをリファクタリングすることは可能ですか?

または、そのようなテストをまとめるためのより良い方法はありますか?

4

2 に答える 2

4

doctest を使用したことはありません。

def genDocText(func_name):
    return r'''
    >>> conn = httplib.HTTPConnection(...)
    >>> %(func_name)s(None, conn)
    Traceback (most recent call last):
    NoneAsInputError: `mystring` should be a string and not `None`!

    >>> %(func_name)s("", conn)
    Traceback (most recent call last):
    EmptyStringError: `mystring` should not be an empty string!
    ''' % {'func_name': func_name}

def function_1(mystring, conn):
    pass

function_1.__doc__ = genDocText('function_1')

これは悪い方法ですか?

更新:デコレータを使用すると、上記のソリューションは次のように記述できます。

def genDocText(func):
    func.__doc__ = r'''
    >>> conn = httplib.HTTPConnection(...)
    >>> %(func_name)s(None, conn)
    Traceback (most recent call last):
    NoneAsInputError: `mystring` should be a string and not `None`!

    >>> %(func_name)s("", conn)
    Traceback (most recent call last):
    EmptyStringError: `mystring` should not be an empty string!
    ''' % {'func_name': func.__name__}
    return func

@genDocText
def function_1(mystring, conn):
    pass

@genDocText
def function_2(mystring, conn):
    pass

@genDocText
def function_n(mystring, conn):
    pass

if __name__ == '__main__':
    print function_1.__doc__
    print function_2.__doc__
    print function_n.__doc__
于 2011-06-19T13:32:13.980 に答える
1

これは直接的な答えではありませんが、重要なポイントだと思いunittestます。コードの重大なテストに使用することを検討してください。doctest素晴らしいですが、制限があります-ドキュメント内のコードの単純なスニペットが実際に機能することを確認する以外には使用しません(注-モジュールではなくスニペットをテストします)。

unittestテストに追加できるカスタマイズの量に非常に制限がなく、コードをより徹底的にテストできるようになります。

于 2011-06-19T13:29:36.867 に答える