python实验三函数的简单介绍( 五 )


string = "ABCDE"
result =[]
for i in range(-2, len(string) + 2):
... result.append(insert_at(string, i,“-”))
result[:5]
【python实验三函数的简单介绍】 ['ABC-DE', 'ABCD-E', '-ABCDE','A-BCDE', 'AB-CDE']
result[5:]
['ABC-DE', 'ABCD-E', 'ABCDE-', 'ABCDE-']
"""
return string
对不返回任何参数的函数或方法(通常返回None),我们通常赋予其由pass构成的一个suite,对那些返回值被试用的,我们或者返回一个常数(比如0),或者某个不变的参数——这也是我们这里所做的 。(在更复杂的情况下 , 返回fake对象可能更有用一一对这样的类,提供mock对象的第三方模块是可用的 。)
运行doctest时会失败,并列出每个预期内的字符串('ABCD-EF'、'ABCDE-F' 等),及其实际获取的字符串(所有的都是'ABCD-EF') 。一旦确定doctest是充分的和正确的,就可以编写该函数的主体部分 , 在本例中只是简单的return string[:position] + insert+string[position:] 。(如果我们编写的是 return string[:position] + insert,之后复制 string [:position]并将其粘贴在末尾以便减少一些输入操作,那么doctest会立即提示错误 。)
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的测试 。运行时,这一特定实例产生如下结果:

推荐阅读