doctest

using

python ./export.py -v

verbose args show the test detail good for u

 

 


Python doctest


>>> def median(pool): 
      
    '''Statistical median to demonstrate doctest. 
      
    >>> median([2, 9, 9, 7, 9, 2, 4, 5, 8]) 
      
    7 
      
    ''' #代码的文档,功能说明。如果运行以上参数,期望结果是7 
      
    copy = sorted(pool) 
      
    size = len(copy) 
      
    if size % 2 == 1: 
      
        return copy[(size-1)/2] 
      
    else : 
      
        return (copy[size/2-1] + copy[size/2])/2 
      

     
      
>>> if __name__ == '__main__': 
      
    import doctest 
      
    doctest.testmod()



运行结果:
TestResults(failed=0, attempted=1)
如果我把上面的7改为8,运行结果如下:

********************************************************************** 
      
File "__main__", line 3, in __main__.median 
      
Failed example: 
      
    median([2, 9, 9, 7, 9, 2, 4, 5, 8]) 
      
Expected: 
      
    8 
      
Got: 
      
    7 
      
********************************************************************** 
      
1 items had failures: 
      
   1 of   1 in __main__.median 
      
***Test Failed*** 1 failures. 
      
*** DocTestRunner.merge: '__main__.median' in both testers; summing outcomes. 
      
*** DocTestRunner.merge: '__main__' in both testers; summing outcomes. 
      
TestResults(failed=1, attempted=1)



doctest模块在程序说明中寻找看起来像python交互程序的字符串,然后把这些字符串作为python代码运行,验证他们运行后是否得到想要的结果。这里有3种需求会用到doctest。
1. 验证模块(例如,方法)中的文档或说明书是否得及时更新。
2. 执行回归测试(regression test)。
3. 写培训文档,或说明文档,有点程序可读性测试的味道。
总之,doctest按文档中的指令执行,其实就是按照预先给定的参数执行该模块,然后对比实际输出结果是否与说明中的结果一致。其结果就反映了以上3个方面,1,有可能程序正确,文档说明没有及时更新;2,修改后的程序有bug;3,由于程序的执行结果与文档说明中的不一致,很可能导致读者困惑,程序可读性受影响。
下面举一个小例子,麻雀虽小五脏俱全。

def factorial (n): 
      
    '''Return the factorial of n, an exact integer >= 0. 
      
    If the result is small enough to fit in an int, return an int. 
      
    Else return a long. 
      
    >>> [factorial(n) for n in range(6)] #看看python的语法就是这么简洁 
      
    [1, 1, 2, 6, 24, 120] 
      
    >>> [factorial(long(n)) for n in range(6)] 
      
    [1, 1, 2, 6, 24, 120] 
      
    >>> factorial(30) 
      
    265252859812191058636308480000000L 
      
    >>> factorial(30L) 
      
    265252859812191058636308480000000L 
      
    >>> factorial(-1) 
      
    Traceback (most recent call last): 
      
    ... 
      
    ValueError: n must be >= 0 
      
     
      
    Factorials of floats are OK, but the float must be an exact integer: 
      
    >>> factorial(30.1) 
      
    Traceback (most recent call last): 
      
    ... 
      
    ValueError: n must be exact integer 
      
    >>> factorial(1e100) 
      
    Traceback (most recent call last): 
      
    ... 
      
    OverflowError: n too large 
      
    ''' #三引号引起来的字都是说明 
      
     
      
    import math 
      
    if not n>=0: 
      
        raise ValueError("n must be >= 0") 
      
    if math.floor(n) != n: 
      
        raise ValueError("n must be exact integer") 
      
    if n+1 == n: # cache a value like le300 
      
        raise OverflowError("n too large") 
      
    result = 1 
      
    factor = 2 
      
    while factor <= n: 
      
        result *= factor 
      
        factor += 1 
      
    return result 
      
     
      
if __name__ == "__main__": 
      
    import doctest 
      
    doctest.testmod()


以上代码需要保存到C:\Python26\Lib\site-packages\win32\test\example.py。然后再命令行里直接运行它:
>python example.py
>
没有输出,那就对了,意味着所有的例子多是正确的。如果命令行后加参数-v,doctest将会把详细的记录打印出来,做一个总结。


转载于:

>>> def median(pool): 
      
    '''Statistical median to demonstrate doctest. 
      
    >>> median([2, 9, 9, 7, 9, 2, 4, 5, 8]) 
      
    7 
      
    ''' #代码的文档,功能说明。如果运行以上参数,期望结果是7 
      
    copy = sorted(pool) 
      
    size = len(copy) 
      
    if size % 2 == 1: 
      
        return copy[(size-1)/2] 
      
    else : 
      
        return (copy[size/2-1] + copy[size/2])/2 
      

     
      
>>> if __name__ == '__main__': 
      
    import doctest 
      
    doctest.testmod()


运行结果:


TestResults(failed=0, attempted=1)


如果我把上面的7改为8,运行结果如下:

doctest模块在程序说明中寻找看起来像python交互程序的字符串,然后把这些字符串作为python代码运行,验证他们运行后是否得到想要的结果。这里有3种需求会用到doctest。

********************************************************************** 
      
File "__main__", line 3, in __main__.median 
      
Failed example: 
      
    median([2, 9, 9, 7, 9, 2, 4, 5, 8]) 
      
Expected: 
      
    8 
      
Got: 
      
    7 
      
********************************************************************** 
      
1 items had failures: 
      
   1 of   1 in __main__.median 
      
***Test Failed*** 1 failures. 
      
*** DocTestRunner.merge: '__main__.median' in both testers; summing outcomes. 
      
*** DocTestRunner.merge: '__main__' in both testers; summing outcomes. 
      
TestResults(failed=1, attempted=1)


1. 验证模块(例如,方法)中的文档或说明书是否得及时更新。


2. 执行回归测试(regression test)。


3. 写培训文档,或说明文档,有点程序可读性测试的味道。


总之,doctest按文档中的指令执行,其实就是按照预先给定的参数执行该模块,然后对比实际输出结果是否与说明中的结果一致。其结果就反映了以上3个方面,1,有可能程序正确,文档说明没有及时更新;2,修改后的程序有bug;3,由于程序的执行结果与文档说明中的不一致,很可能导致读者困惑,程序可读性受影响。


下面举一个小例子,麻雀虽小五脏俱全。

def factorial (n): 
      
    '''Return the factorial of n, an exact integer >= 0. 
      
    If the result is small enough to fit in an int, return an int. 
      
    Else return a long. 
      
    >>> [factorial(n) for n in range(6)] #看看python的语法就是这么简洁 
      
    [1, 1, 2, 6, 24, 120] 
      
    >>> [factorial(long(n)) for n in range(6)] 
      
    [1, 1, 2, 6, 24, 120] 
      
    >>> factorial(30) 
      
    265252859812191058636308480000000L 
      
    >>> factorial(30L) 
      
    265252859812191058636308480000000L 
      
    >>> factorial(-1) 
      
    Traceback (most recent call last): 
      
    ... 
      
    ValueError: n must be >= 0 
      
     
      
    Factorials of floats are OK, but the float must be an exact integer: 
      
    >>> factorial(30.1) 
      
    Traceback (most recent call last): 
      
    ... 
      
    ValueError: n must be exact integer 
      
    >>> factorial(1e100) 
      
    Traceback (most recent call last): 
      
    ... 
      
    OverflowError: n too large 
      
    ''' #三引号引起来的字都是说明 
      
     
      
    import math 
      
    if not n>=0: 
      
        raise ValueError("n must be >= 0") 
      
    if math.floor(n) != n: 
      
        raise ValueError("n must be exact integer") 
      
    if n+1 == n: # cache a value like le300 
      
        raise OverflowError("n too large") 
      
    result = 1 
      
    factor = 2 
      
    while factor <= n: 
      
        result *= factor 
      
        factor += 1 
      
    return result 
      
     
      
if __name__ == "__main__": 
      
    import doctest 
      
    doctest.testmod()


以上代码需要保存到C:\Python26\Lib\site-packages\win32\test\example.py。然后再命令行里直接运行它:


>python example.py


>


没有输出,那就对了,意味着所有的例子多是正确的。如果命令行后加参数-v,doctest将会把详细的记录打印出来,做一个总结。