Python 测试框架: 寻找要测试的模块(2)

来源:developerWorks 中国 作者:developerWorks 中国
  





在测试套件中包含 docfile 和 doctest

在比较长的文档中,由三个大于号组成的 Python 提示符 >>> 是一个非常明显的标志,它表示在 Python 提示上应该发生什么。正如在本系列的第一篇文章中看到的,这可以出现在作为文档的单独的文本文件中:

Doctest for truth and falsehood
-------------------------------

The truth values in Python, named "True" and "False",
are equivalent to the Boolean numbers one and zero.

>>> True == 1
True
>>> False == 0
True

这种说明还可以出现在源代码中模块、类或函数的 docstring 中:

def count_vowels(s):
    """Count the number of vowels in a string.

    >>> count_vowels('aardvark')
    3
    >>> count_vowels('THX')
    0

    """
    return len( c for c in s if c in 'aeiou')

当这些测试出现在文本文件中时(比如第一个示例),文件就被称为 docfile。当它们出现在 Python 源代码中的 docstring 中时(比如第二个示例),它们就被称为 doctest。

因为 docfile 和 doctest 是编写作为测试使用的文档的常用方法(而且这也能够表明文档什么时候过时了),所以 py.test 和 nose 直接支持它们。(zope.testing 的用户必须使用标准 doctest 模块中的 DocTestSuite 类为每个文件手工创建 Python 测试用例)。

与用于寻找测试模块的规则一样,py.test 框架采用固定的过程支持 doctest,无法进行配置,这在项目之间实现标准化,但是限制了项目的灵活性。

  • 如果启用了它的 -p doctest 插件,它就会在所有 Python 模块(包括模块名中不包含 test 的模块)的文档字符串中以及以 test_ 开头和以 .txt 扩展名结尾的所有文本文件中寻找 doctest。
  • 如果启用了它的 -p restdoc 插件,那么不但执行 .txt 文件中的所有 doctest,py.test 还要求项目中的每个 .txt 文件都是有效的 Restructured Text 文件,如果它们造成解析错误,py.test 会发出警告。还可以通过命令行选项让这个插件检查文档中指定的 URL,然后生成每个 .txt 文本文件的 HTML 版本。

nose 支持非常相似的特性集,但是更灵活。

  • --doctest-tests 是干扰最小的选项,它只要求 nose 在已经检查的测试模块的 docstring 中寻找 doctest。
  • --with-doctest 选项的影响比较大,它要求 nose 搜索所有一般模块(不是测试但包含一般代码的模块),寻找并运行它们的 docstring 中的 doctest。
  • 最后,--doctest-extension 允许指定文件扩展名(我认识的大多数开发人员选择 .txt、.rst 或 .doctest)。这要求 nose 读取项目中具有指定的扩展名的所有文本文件,运行并检查它找到的所有 doctest。

尽管 py.test 和 nose 在这方面的特性集非常相似,但是我更喜欢 nose 的方式。我喜欢对所有 Restructured Text 文件使用非标准的 .rst 扩展名,这样就可以让文本编辑器能够识别它们并对它们应用特殊的语法突出显示。





nose 框架和可执行模块

对于 nose 框架应该注意一点:它在默认情况下回避那些标为可执行的 Python 模块。(在 Linux® 上,可以使用 chmod +x 这样的命令把文件标为可执行命令)。nose 框架忽略这样的文件,因为这些模块被设计为直接从命令行运行,它们可能执行某些对于 import 不安全的操作。

但是,可以用一个 if 语句检查模块是直接运行还是导入,从而保护它们执行的实际操作,这样就可以安全地导入命令:

#!/usr/bin/env python
# Sample Python command

if __name__ == '__main__':
print "This has been run from the command line!"

如果对每个命令都采用这种保护措施,因此知道它们是可以安全地导入的,那么就可以通过 --exe 命令行选项让 nose 检查可执行模块。

在这个方面,我更喜欢 py.test 的做法:它不考虑 Python 模块是否是可执行的,这使它的规则比 nose 的规则简单,并强制实施最佳实践(比如用 if 语句保护命令逻辑)。但是,如果要对遗留应用程序使用测试框架,程序可能包含许多代码质量不确定的可执行模块,那么 nose 似乎是更安全的工具。





结束语

本文详细讨论了这三种 Python 测试框架如何检查代码基并选择它们认为包含测试的模块。通过提供基于统一约定的自动发现,这三种测试框架都有助于编写更一致的测试套件,框架可以自动地检测和检查它们。但是,测试框架接下来会做什么?它们会在这些模块内寻找 什么?这是 本系列 的第三篇文章的主题!(责任编辑:A6)


时间:2009-07-20 13:18 来源:developerWorks 中国 作者:developerWorks 中国 原文链接

好文,顶一下
(3)
100%
文章真差,踩一下
(0)
0%
------分隔线----------------------------


把开源带在你的身边-精美linux小纪念品
无觅相关文章插件,快速提升流量