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 回答