摘要:Python是一种敏捷开发项目经常采用的语言。本文介绍了在Python敏捷项目中结合类似epydoc文档系统,使在doctest单元测试同时能够产生同步的最新文档,比如常用的功能说明文档等,在敏捷开发中常被称作敏捷文档。
关键词:Python;敏捷开发;敏捷文档;doctest;单元测试;执行文档;epydoc
中图分类号:TP311文献标识码:A文章编号:1009-3044(2007)04-11058-02
1 引言
在敏捷开发中单元测试是不可或缺的环节,单元测试除了保证了代码的质量外,在测试驱动开发中,测试更被改变地位,成为驱动开发主导的地位,每个功能的增加都必须写响应的单元测试以明确功能增加的目的性,形成的“测试-编码-重整”开发循环是敏捷开发的重要内容。
众所周知,撰写文档是软件开发的重要部分。在测试驱动开发,程序员在单元测试中留下了大量的功能说明和功能使用代码,这些正是软件功能说明文档的素材,在python中利用doctest框架写出的单元测试更符合说明文档的需要,所以结合doctest和文档系统(epydoc)我们否找到一种方法:利用单位测试的注释和代码直接形成规格化的
功能说明文档。
2 doctest
2.1 doctest介绍
在Python中doctest就是把程序中的docstring作为范例来运行的一个框架。
docstring可以由普通部分和执行部分组成,普通部分等同于原来的文字说明,执行部分由'>>>'(python shell提示符)或'...'提示符区分。程序员可以通过手工编写可预测的执行部分,也可以通过拷贝复制python交互式shell中的输入和输出简单的形成执行部分,doctest搜寻存在与各个模块,类和函数中的docstring,把每个可执行部分当成一次范例运行,再把实际运行值和期望值的对照作为一次运行结果。
2.2 doctest:单元测试的新框架
doctest常常用来完成三方面任务:保持文档与代码的同步;实现回归测试;可执行文档。这样就给测试框架多的Python又增加了一个不错的选择,对比其他测试框架(如unittest;py.test等)doctest具备了如下一些特点:
(1)无需安装,从python 2.1版本开始被纳入标准库;
(2)没有调用接口,使用方便,只需复制粘贴python shell中交互输入输出;
(3)通过命令行参数可灵活控制测试的执行;
(4)能很好地保持文档和代码的同步;
(5)测试用例也独立存在与代码分离的文件中,它们可以包含特殊的边界测试用例等;
(6)利用增强选项可增强输出文本匹配能力,比如ellipses选项,使地址,浮点数等可变输出得到正确匹配;
(7)利用_test_变量,灵活选择测试用的docstring。
利用doctest实现单元测试时,程序员独立创建只包含docstring的无函数体的测试函数实现测试单元,然后在docstring中编写测试说明和测试代码,它们是包含被测试目标的一些运行范例和期望的结果,利用doctest运行这些测试单元。
我们约定在一个被测试模块中包含的所有测试单元列表称为:testlist;而模块中被测试目标所有测试单元的列表称为testmap。
3 方法:结合单元测试doctest和epydoc开发敏捷文档
epydoc是Python中一个功能强大的文档系统,结合类似epydoc这样的文档系统,使基于doctest的单元测试能够产生和代码同步的最新文档,这种文档不仅展示了代码中包含的所多个模块、类、方法、函数、变量,更重要的是,它还能提供许多程序功能的“动态的”使用范例。
3.1 方法步骤
我们下面将模拟doctest的单元测试过程,在docstring加入epydoc链接,最后用epydoc输出文档。
(1)我们准备了要进行单元测试的模块P,包含一个类C;
(2)我们开始给模块P中的C.M1方法写单元测试。
方法是:在Python的交互窗口中运行C.M1的测试代码,然后复制&粘贴刚才的输入和输出到一个新的Python模块文件中(testlist_P),命名单元测试函数为test_M1,例子如下:
def test_M1():
"""
对M1测试行为的简短描述
被测试目标:
- L{P.C.M1}
testlist_P模块的main部分如下:
if _name_ == "_main_":
import doctest
doctest.testmod()
这是doctest在单元测试中典型的运行方式。实际运行测试时,我们只需在命令行方式下输入“python testfile_P.py”。
(3)现在,我们给方法C.M1补充初步的实现代码。在M1的docstring中,我们还增加一个Test Map的链接:
def M1(self):
"""
M1的描述
Test map:
- L{testmap_P.testmap_C_M1}
"""
(4)利用程序自动生成我们需要的模块P的Test Map,命名为testmap_P.py,其中C.M1的Test map内容(即所有测试到C.M1的测试单元列表)如下:
def testmap_C_M1():
"""
Testmap for L{P.C.M1}:
- L{testlist_P.test_M1}
"""
(5)调用epydoc输出文档:
epydoc -o P_docs P.py testlist_P.py testmap_P.py
输出的文档在P_docs目录下,由于都是HTML格式文件,我们只需把它们移到web服务器文档目录下来就能发布出在线文档。
当我们点击testlist_P模块链接,我们会看到模块P的testlist:
Module P_docs.testlist_P
当我们点击方法C.M1的docstring中的testmap链接,我们可以看到C.M1的testmap:
Testmap for P.C.M1:
* testlist_P.test_M1
为C.M2重复步骤2-5
(6)假设我们在单元测试方法M2时,同时也对M1测试,那么M2的测试函数test_M2可能是:
def test_M2():
"""
对M2测试行为的简短描述
被测试目标
- L{P.C.M1}
- L{P.C.M2}
>>> from P import C
>>> c = C()
>>> rc = c.M1()
>>> print rc
True
>>> rc = c.M2()
>>> print rc
True
"""
在“被测试目标”中,我们把两个函数都列出来了
(7)在方法M2的docstring中添加testmap链接:
def M2(self):
"""
M2的描述
Test map:
- L{testmap_P.testmap_C_M2}
"""
(8)利用程序重新生成模块的testmap,结果保存在testmap_P中,现在,C.M1的testmap将包含两个函数:test_M1,test_M2,而C.M2的testmap则包含test_M2:
def testmap_C_M1():
"""
Testmap for L{P.C.M1}:
- L{testlist_P.test_M1}
- L{testlist_P.test_M2}
"""
def testmap_C_M2():
"""
Testmap for L{P.C.M2}:
- L{testlist_P.test_M2}
"""
(9)运行epydoc输出文档:
epydoc -o P_docs P.py testlist_P.py testmap_P.py
我们点击testlist_P链接将看到:
Module P_docs.testlist_P
点击方法C.M1的docstring中的testmap链接:
testmap_C_M1()
Testmap for P.C.M1:
* testlist_P.test_M1
* testlist_P.test_M2
(10)重复步骤2-5把每个单元测试添加到testlist_P模块中
4 结束语
我们可以发现doctest、epydoc的结合使得产生功能说明文档变得非常方便,同时也非常强大。这里敏捷文档或许还被称作"literate testing"被看的见的测试或"executable documentation"可执行的文档,但不管如何称呼,名字看来是不重要的,重要的是我们得到一种方法:我们通过单元测试docstring中的代码的方式,文档化模块的功能,没有比这更敏捷的方法了。
参考文献:
[1]Robert C·Martin. 敏捷软件开发——原则、模式与实践[M]. 清华大学出版社,2006.
[2]Python Library Reference. http://docs.python.org/lib/module-doctest.html.
[3]Epydoc Homepage. http://epydoc.sourceforge.net/.
本文中所涉及到的图表、注解、公式等内容请以PDF格式阅读原文。
分享到:
相关推荐
在"在Python中结合doctest和Epydoc产生敏捷文档的一种方法.pdf"这个文件中,可能详细阐述了如何设置和使用这两个工具,包括具体配置、示例代码以及实践中的注意事项。建议阅读该文件以获取更深入的了解和实践指导。
本文探讨了一种方法,即通过结合Python的doctest和Epydoc工具,使开发人员在编写单元测试的同时,能够自动生成敏捷文档。 敏捷文档的概念是相对于传统文档而言的,它强调的是文档的更新应与软件开发的迭代过程保持...
12. **模块`doctest`**:一种内建的测试工具,可以检查程序文档字符串中的交互式示例是否正确。 13. **高级话题**:如装饰器、生成器、协程和上下文管理器,这些都是Python中高级特性的体现,有助于编写更高效和...
我们首先需要在一个Python文件中编写函数和对应的测试代码,测试代码通常嵌入在函数的文档字符串中。当运行doctest模块时,它会检查这些文档字符串,查找以>>>开头的交互式Python会话,并验证这些会话的输出是否与...
文档测试是Python的一种内建测试机制,主要用于测试函数或方法中的docstring(文档字符串)。通过在函数的docstring中编写简单的测试示例,开发者可以在开发过程中方便地进行快速验证。Python提供了`doctest`模块来...
Python标准库中的`doctest`模块提供了一种简洁的方式来集成测试到代码的文档字符串中,使得测试和代码更加紧密地结合。以下将详细介绍`doctest`模块的使用方法和相关知识点。 首先,`doctest`模块的核心功能是扫描...
Python测试模块doctest是Python标准库中的一个模块,它允许开发者将简单的测试用例直接嵌入到Python程序的文档字符串中。doctest模块主要被用来做交互式测试,它可以通过检查文档字符串中嵌入的交互式Python会话来...
`doctest` 库提供了一种方法,可以在不增加额外测试代码的情况下,直接从注释中提取测试用例。这样,当开发者更新了函数或方法的行为时,他们只需更新文档中的示例,而`doctest`会自动检查这些示例是否仍然有效,...
Python是一种广泛使用的高级编程语言,以其易读性、简洁的语法和强大的功能而闻名。它在科学计算、数据处理、Web开发和自动化任务等领域有着广泛的应用。本"Python中文操作手册"是针对Python编程者的重要参考资料,...
以上内容涵盖了Python 2.7学习文档中的主要知识点,为初学者提供了一个全面的学习框架。通过系统学习这些内容,不仅可以掌握Python的基本语法,还能深入理解其高级特性,为日后进一步的技术发展奠定坚实的基础。
生成器和迭代器是Python特有的概念,它们提供了一种更加高效的方式处理大量数据,尤其是当数据集非常大时,可以做到按需生成数据,而不是一次性加载到内存中。 4. 函数式编程 函数式编程是Python支持的编程范式之一...
这个文档集合是基于官方的英文文档通过机器翻译而成,虽然可能在语言精确度上存在一些出入,但总体上能够帮助中文用户更好地理解和应用Python的标准库。 Python标准库是Python编程语言的核心组成部分,它包含了大量...
Python 2.5.2 API文档是Python编程语言在2.5.2版本时的官方技术参考手册,它以CHM(Compiled HTML Help)格式提供,这种格式是一种由微软开发的用于存储和检索HTML帮助文档的系统。这篇文档是Python开发者、学习者和...
8. 非侵入式测试(Non-Intrusive Testing):Python的`doctest`模块可以从文档字符串中提取测试,这样可以确保代码示例同时作为测试,保证代码的可用性和文档的一致性。 9. 持续集成/持续部署(Continuous ...
Python是一种高级编程语言,以其简洁明了的语法和强大的功能而受到全球开发者的喜爱。Python的官方文档是学习和理解该语言的重要资源,它包含了语言规范、标准库、开发工具和指南等内容,对于初学者和经验丰富的...