本文进行着重讲述有关Python 模块的问题和技巧,在讲解Python 模快之前首先先让大家了解下什么是Python语言,所谓Python:是一种面向对象、直译式计算机程序设计语言,也是一种功能强大而完善的通用型语言。
但是,它们采用的测试发现规则不太一样,在选择框架时需要考虑到这一点。测试框架执行的第一步是,选择将在哪些目录中搜索包含测试的文件。注意,这三种框架都从整个项目的基目录开始搜索;如果要测试名为 example 的包,那么它们会从包含 example 的父目录开始搜索测试。
但是,这三种框架在选择搜索哪些目录方面有所差异:zope.testing 工具向下递归地搜索是 Python 包的所有目录,也就是包含 __init__.py 文件的目录(对于Python 模块,这说明可以用 import 语句导入它们)。
这意味着不检查非包目录中的数据和代码,但是另一方面,这也意味着从理论上说程序员可以用 import 语句导入您编写的每个测试。一些程序员觉得这让人不舒服,希望能够把测试放在包的一般用户看不到的地方。
py.test 命令向下递归地搜索项目的每个目录和子目录,无论目录是否是 Python 包。注意,当两个相邻目录包含同名的测试时,它似乎有一个 bug。例如,如果相邻的dir1/test.py 和 dir2/test.py 文件都包含名为 test_example 的测试,那么 py.test 将运行第一个测试两次。
而完全忽略第二个测试!如果为 py.test 编写测试并把它们放在非包目录中,就要注意保持名称是惟一的。nose 测试运行器采用的实现方式介于另两种工具之间:它向下递归地搜索每个 Python 包,但是只检查目录名中包含单词 test 的目录。
这意味着,如果不想让 nose 搜索某个目录,那么只需注意不在目录名中包含 test 即可。与 py.test 不同,nose 可以正确地处理包含同名测试的相邻目录(但是保持测试名称惟一仍然是有帮助的,这样在用 -v 选项显示测试结果时不容易混淆)。
选择了要搜索的目录之后,这三种测试工具的做法就非常相似了:它们都寻找与某一模式匹配的 Python 模块(也就是以 .py 结尾的文件)。zope.testing 工具在默认情况下使用正则表达式 "tests",也就是只寻找名为 tests.py 的文件,忽略其他所有文件。可以使用命令行选项或 buildout.cfg 指定另一个正则表达式
:
- # Snippet of a buildout.cfg file that searches for tests
- # in any Python module starting with "test" or "ftest".
- [test]
- recipe = zc.recipe.testrunner
- eggs = my_package
- defaults = ['--tests-pattern', 'f?test']
py.test 更死板,总是寻找名称以 `test_ 开头或以 _test 结尾的 Python 模块。nosetests 命令更灵活,它使用一个正则表达式(“((?:^|[\b_\.-])[Tt]est)”)选择以 test 或 Test 开头或这个单词处于单词边界后面的模块。通过在命令行上使用 -m 选项或在项目的 .noserc 文件中设置这个选项,可以指定另一个正则表达式。
哪种方法最好?尽管一些开发人员喜欢有灵活性,而且许多人认为 zope.testing 工具的搜索范围应该更宽,不应该只限于文件名为 tests.py 的模块,但是我实际上更喜欢 py.test 采用的方式。
所有使用 py.test 的项目必须在测试命名方面采用一致的约定,这让其他程序员更容易阅读和维护测试。在使用另外两种框架时。阅读或创建测试文件需要两步:首先,必须了解这个项目使用的正则表达式,然后才能检查它的代码。如果您同时从事多个项目,就必须记住几种不同的测试文件命名约定。