python函数性能 python代码( 二 )


Python的标准库提供了两个单元测试模块,一个是doctest,这里和前面都简单地提到过,另一个是unittest 。此外,还有一些可用于Python的第三方测试工具 。其中最著名的两个是nose (code.google.com/p/python-nose)与py.test (codespeak.net/py/dist/test/test.html), nose 致力于提供比标准的unittest 模块更广泛的功能,同时保持与该模块的兼容性,py.test则采用了与unittest有些不同的方法,试图尽可能消除样板测试代码 。这两个第三方模块都支持测试发现,因此没必要写一个总体的测试程序——因为模块将自己搜索测试程序 。这使得测试整个代码树或某一部分 (比如那些已经起作用的模块)变得很容易 。那些对测试严重关切的人 , 在决定使用哪个测试工具之前,对这两个(以及任何其他有吸引力的)第三方模块进行研究都是值 得的 。
创建doctest是直截了当的:我们在模块中编写测试、函数、类与方法的docstrings 。对于模块,我们简单地在末尾添加了 3行:
if __name__ =="__main__":
import doctest
doctest.testmod()
在程序内部使用doctest也是可能的 。比如,blocks.py程序(其模块在后面)有自己函数的doctest , 但以如下代码结尾:
if __name__== "__main__":
main()
这里简单地调用了程序的main()函数,并且没有执行程序的doctest 。要实验程序的 doctest,有两种方法 。一种是导入doctest模块,之后运行程序---比如 , 在控制台中输 入 python3 -m doctest blocks.py (在 Wndows 平台上,使用类似于 C:Python3 lpython.exe 这样的形式替代python3) 。如果所有测试运行良好 , 就没有输出,因此,我们可能宁愿执行python3-m doctest blocks.py-v,因为这会列出每个执行的doctest,并在最后给出结果摘要 。
另一种执行doctest的方法是使用unittest模块创建单独的测试程序 。在概念上,unittest模块是根据Java的JUnit单元测试库进行建模的,并用于创建包含测试用例的测试套件 。unittest模块可以基于doctests创建测试用例,而不需要知道程序或模块包含的任何事物——只要知道其包含doctest即可 。因此,为给blocks.py程序制作一个测试套件,我们可以创建如下的简单程序(将其称为test_blocks.py):
import doctest
import unittest
import blocks
suite = unittest.TestSuite()
suite.addTest(doctest.DocTestSuite(blocks))
runner = unittest.TextTestRunner()
print(runner.run(suite))
注意 , 如果釆用这种方法 , 程序的名称上会有一个隐含的约束:程序名必须是有效的模块名 。因此 , 名为convert-incidents.py的程序的测试不能写成这样 。因为import convert-incidents不是有效的,在Python标识符中,连接符是无效的(避开这一约束是可能的,但最简单的解决方案是使用总是有效模块名的程序文件名 , 比如,使用下划线替换连接符) 。这里展示的结构(创建一个测试套件,添加一个或多个测试用例或测试套件,运行总体的测试套件,输出结果)是典型的机遇unittest的测试 。运行时,这一特定实例产生如下结果:
...
.............................................................................................................
Ran 3 tests in 0.244s
OK
每次执行一个测试用例时,都会输出一个句点(因此上面的输出最前面有3个句点),之后是一行连接符 , 再之后是测试摘要(如果有任何一个测试失败,就会有更多的输出信息) 。
如果我们尝试将测试分离开(典型情况下是要测试的每个程序和模块都有一个测试用例),就不要再使用doctests,而是直接使用unittest模块的功能——尤其是我们习惯于使用JUnit方法进行测试时ounittest模块会将测试分离于代码——对大型项目(测试编写人员与开发人员可能不一致)而言 , 这种方法特别有用 。此外,unittest单元测试编写为独立的Python模块,因此 , 不会像在docstring内部编写测试用例时受到兼容性和明智性的限制 。

推荐阅读