doctest模块搜索类似于交互式Python会话的文本段,然后执行这些会话来验证他们是否如所示的那样。有一些常见使用doctest的方式:
- 通过检测所有的文档中的交互式例子输出正常来检查一个模块的文档字符串为最新的。
- 通过验证来自测试文件或者测试对象的交互式例子的输出像预期一样来执行回归测试。
- 为一个包编写教程文档,逐字地用输入-输出例子来说明。取决与这个例子或者说明文本是否强调,有些“逐字测试”或者“可执行文档”的味道。
以下是一个来自官方文档中的例子:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
"""
This is the "example" module.
The example module supplies one function, factorial(). For example,
>>> factorial(5)
120
"""
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)]
[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(30.0)
265252859812191058636308480000000L
It must also not be ridiculously large:
>>> 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: # catch a value like 1e300
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()
This is the "example" module.
The example module supplies one function, factorial(). For example,
>>> factorial(5)
120
"""
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)]
[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(30.0)
265252859812191058636308480000000L
It must also not be ridiculously large:
>>> 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: # catch a value like 1e300
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()
这里有个很有趣的地方,如果你将这个脚本保存为doctest.py,并且运行,你会得到以下结果:
Traceback (most recent call last):
File "/home/nupta/doctest.py", line 62, in <module>
doctest.testmod()
AttributeError: 'module' object has no attribute 'testmod'
File "/home/nupta/doctest.py", line 62, in <module>
doctest.testmod()
AttributeError: 'module' object has no attribute 'testmod'
刚开始,我也百得不思其解,后来查了下资料,发现在交互模式下,查看doctest的函数时,猛地发现原来是被重写了,a good lesson...
![](https://images.cnblogs.com/cnblogs_com/yuxc/201109/Screenshot.png)
简单地把文件名改成doctest1.py之后,需要删除之前的pyc文件。运行结果如下,空空如也,表示一切正常:
>>>
加上参数-v,则会在打印出每个尝试的细节日志,并在最后给出一个统计概要。
Trying:
factorial(5)
Expecting:
120
ok
Trying:
[factorial(n) for n in range(6)]
Expecting:
[1, 1, 2, 6, 24, 120]
ok
Trying:
[factorial(long(n)) for n in range(6)]
Expecting:
[1, 1, 2, 6, 24, 120]
ok
Trying:
factorial(30)
Expecting:
265252859812191058636308480000000L
ok
Trying:
factorial(30L)
Expecting:
265252859812191058636308480000000L
ok
Trying:
factorial(-1)
Expecting:
Traceback (most recent call last):
...
ValueError: n must be >= 0
ok
Trying:
factorial(30.1)
Expecting:
Traceback (most recent call last):
...
ValueError: n must be exact integer
ok
Trying:
factorial(30.0)
Expecting:
265252859812191058636308480000000L
ok
Trying:
factorial(1e100)
Expecting:
Traceback (most recent call last):
...
OverflowError: n too large
ok
2 items passed all tests:
1 tests in __main__
8 tests in __main__.factorial
9 tests in 2 items.
9 passed and 0 failed.
Test passed.
factorial(5)
Expecting:
120
ok
Trying:
[factorial(n) for n in range(6)]
Expecting:
[1, 1, 2, 6, 24, 120]
ok
Trying:
[factorial(long(n)) for n in range(6)]
Expecting:
[1, 1, 2, 6, 24, 120]
ok
Trying:
factorial(30)
Expecting:
265252859812191058636308480000000L
ok
Trying:
factorial(30L)
Expecting:
265252859812191058636308480000000L
ok
Trying:
factorial(-1)
Expecting:
Traceback (most recent call last):
...
ValueError: n must be >= 0
ok
Trying:
factorial(30.1)
Expecting:
Traceback (most recent call last):
...
ValueError: n must be exact integer
ok
Trying:
factorial(30.0)
Expecting:
265252859812191058636308480000000L
ok
Trying:
factorial(1e100)
Expecting:
Traceback (most recent call last):
...
OverflowError: n too large
ok
2 items passed all tests:
1 tests in __main__
8 tests in __main__.factorial
9 tests in 2 items.
9 passed and 0 failed.
Test passed.
如何使用呢,比如说我们编写了一个模块M,在docstring中写了输入-输出,那么只要在文档中加入以下代码即可:
if __name__ == "__main__":
import doctest
doctest.testmod()
import doctest
doctest.testmod()
自从Python2.6之后,可以直接在命令行敲上命令运行testmod()来检测:
python -m doctest -v example.py
这次简单地介绍了下doctest在测试代码时的简单使用,总结一下,doctest的好处在于写代码的同时就写下了测试代码,而且又是很好的注释。