<p>下面是一个精心设计的示例,说明如何使用<a href="http://docs.python.org/3/library/doctest.html" rel="nofollow">doctest</a>和测试驱动开发,与通过在控制台输入代码进行测试进行比较,并以递归阶乘函数为例:</p>
<p>控制台:</p>
<p>第一次尝试:</p>
<pre><code>def factorial(x)
pass
</code></pre>
<p>控制台:</p>
<pre><code>>>> factorial(7)
SyntaxError: invalid syntax
</code></pre>
<p>第二次尝试:</p>
<pre><code>def factorial(x):
return x*x-1
</code></pre>
<p>控制台:</p>
<pre><code>>>> factorial(7)
42
</code></pre>
<p>第三次尝试:</p>
<pre><code>def factorial(x):
return x * factorial(x-1)
</code></pre>
<p>控制台:</p>
<pre><code>>>> factorial(7)
RuntimeError: maximum recursion depth reached # StackOverflow! (basically)
</code></pre>
<p>第四次尝试:</p>
<pre><code>def factorial(x):
if x == 0:
return 1
else:
return x * factorial(x-1)
</code></pre>
<p>控制台:</p>
<pre><code>>>> factorial(5)
120
</code></pre>
<p>最后,我们得到了正确的答案,但在每个阶段,我们都必须返回到控制台并编写相同的内容。对于这样一个简短的程序来说,这是可以的,但是对于一个具有许多功能、更复杂的交互和测试可能性的程序来说,这将需要很长的时间。编程是关于自动化重复的任务,而测试是一个重复的任务,所以自动化它是有意义的。在Python中,为您提供了实现这一点的工具。你知道吗</p>
<p>请看-doctest模块:(示例取自docs)</p>
<p>第一次尝试:</p>
<pre><code>def factorial(n):
"""Return the factorial of n, an exact integer >= 0.
>>> [factorial(n) for n in range(6)]
[1, 1, 2, 6, 24, 120]
>>> factorial(30)
265252859812191058636308480000000
>>> 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)
265252859812191058636308480000000
It must also not be ridiculously large:
>>> factorial(1e100)
Traceback (most recent call last):
...
OverflowError: n too large
"""
if __name__ == "__main__":
import doctest
doctest.testmod(verbose=True)
</code></pre>
<p>第一次测试(只需运行程序):</p>
<pre><code>Trying:
[factorial(n) for n in range(6)]
Expecting:
[1, 1, 2, 6, 24, 120]
ok
Trying:
factorial(30)
Expecting:
265252859812191058636308480000000
ok
Trying:
factorial(-1)
Expecting:
Traceback (most recent call last):
...
ValueError: n must be >= 0
ok
Trying:
factorial(30.1)
Expecting:
Traceqwrqaeqrback (most recent call last):
...
ValueError: n must be exact integer
**********************************************************************
File "C:/Python33/doctestex.py", line 14, in __main__.factorial
Failed example:
factorial(30.1)
Exception raised:
Traceback (most recent call last):
File "C:\Python33\lib\doctest.py", line 1287, in __run
compileflags, 1), test.globs)
File "<doctest __main__.factorial[3]>", line 1, in <module>
factorial(30.1)
File "C:/Python33/doctestex.py", line 32, in factorial
raise ValueError("n must be exact integer")
ValueError: n must be exact integer
Trying:
factorial(30.0)
Expecting:
265252859812191058636308480000000
ok
Trying:
factorial(1e100)
Expecting:
Traceback (most recent call last):
...
OverflowError: n too large
ok
1 items had no tests:
__main__
**********************************************************************
1 items had failures:
1 of 6 in __main__.factorial
6 tests in 2 items.
5 passed and 1 failed.
***Test Failed*** 1 failures.
>>> ================================ RESTART ================================
>>>
Trying:
[factorial(n) for n in range(6)]
Expecting:
[1, 1, 2, 6, 24, 120]
**********************************************************************
File "C:/Python33/doctestex.py", line 4, in __main__.factorial
Failed example:
[factorial(n) for n in range(6)]
Expected:
[1, 1, 2, 6, 24, 120]
Got:
[None, None, None, None, None, None]
Trying:
factorial(30)
Expecting:
265252859812191058636308480000000
**********************************************************************
File "C:/Python33/doctestex.py", line 6, in __main__.factorial
Failed example:
factorial(30)
Expected:
265252859812191058636308480000000
Got nothing
Trying:
factorial(-1)
Expecting:
Traceback (most recent call last):
...
ValueError: n must be >= 0
**********************************************************************
File "C:/Python33/doctestex.py", line 8, in __main__.factorial
Failed example:
factorial(-1)
Expected:
Traceback (most recent call last):
...
ValueError: n must be >= 0
Got nothing
Trying:
factorial(30.1)
Expecting:
Traceback (most recent call last):
...
ValueError: n must be exact integer
**********************************************************************
File "C:/Python33/doctestex.py", line 14, in __main__.factorial
Failed example:
factorial(30.1)
Expected:
Traceback (most recent call last):
...
ValueError: n must be exact integer
Got nothing
Trying:
factorial(30.0)
Expecting:
265252859812191058636308480000000
**********************************************************************
File "C:/Python33/doctestex.py", line 18, in __main__.factorial
Failed example:
factorial(30.0)
Expected:
265252859812191058636308480000000
Got nothing
Trying:
factorial(1e100)
Expecting:
Traceback (most recent call last):
...
OverflowError: n too large
**********************************************************************
File "C:/Python33/doctestex.py", line 22, in __main__.factorial
Failed example:
factorial(1e100)
Expected:
Traceback (most recent call last):
...
OverflowError: n too large
Got nothing
1 items had no tests:
__main__
**********************************************************************
1 items had failures:
6 of 6 in __main__.factorial
6 tests in 2 items.
0 passed and 6 failed.
***Test Failed*** 6 failures.
</code></pre>
<p>然后当我们完成程序时(以及在这两个阶段之间的所有阶段),我们只需按下一个按钮,就可以完成所有的测试。例如,如果您与一个团队一起处理一个更大的项目,您可以将测试数据写入文件,并使用失败来查看您需要关注的地方。你知道吗</p>
<pre><code>Trying:
[factorial(n) for n in range(6)]
Expecting:
[1, 1, 2, 6, 24, 120]
ok
Trying:
factorial(30)
Expecting:
265252859812191058636308480000000
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:
265252859812191058636308480000000
ok
Trying:
factorial(1e100)
Expecting:
Traceback (most recent call last):
...
OverflowError: n too large
ok
1 items had no tests:
__main__
1 items passed all tests:
6 tests in __main__.factorial
6 tests in 2 items.
6 passed and 0 failed.
Test passed.
</code></pre>
<p>而且(假设您将所有测试用例添加到docstring中)现在您可以发布或集成程序或其他任何程序,并且它的bug比您在每次更改时只测试您认为重要的东西,而不是在开发过程开始时您认为可能重要的东西要少得多。你知道吗</p>
<p>更不用说你现在有了你的文件基础!在控制台中运行程序,然后输入<code>help(factorial)</code>,现在可以得到:</p>
<pre><code>Help on function factorial in module __main__:
factorial(n)
Return the factorial of n, an exact integer >= 0.
>>> [factorial(n) for n in range(6)]
[1, 1, 2, 6, 24, 120]
>>> factorial(30)
265252859812191058636308480000000
>>> 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)
265252859812191058636308480000000
It must also not be ridiculously large:
>>> factorial(1e100)
Traceback (most recent call last):
...
OverflowError: n too large
</code></pre>
<p>然后可以使用许多工具(<a href="http://docs.python.org/3/library/pydoc.html" rel="nofollow">pydoc</a>是标准库中的一个工具)将docstring转换为格式化的HTML帮助文件。你知道吗</p>
<p>当然,这只是可以与Python一起使用的许多测试工具之一。其他的包括功能更强大的<a href="http://docs.python.org/3/library/unittest.html" rel="nofollow">unittest</a>模块,以及将<code>assert</code>语句添加到代码中的功能较弱的技术。你知道吗</p>