Python测试框架: 寻找要测试的模块
作者:网络转载 发布时间:[ 2015/10/16 15:33:40 ] 推荐标签:软件测试 单元测试
Python 编程社区非常重视单元测试和功能性测试。这种风气不但有助于确保组件和应用程序**的质量,还促使程序员不断调整和改进代码。
本文是讨论现代 Python 测试框架的 三篇系列文章 的第二篇。本系列中的 第一篇文章 介绍了 zope.testing、py.test 和 nose,介绍它们如何影响 Python 项目编写和维护测试的方式。本文介绍如何调用这三种框架、它们如何在项目中发现测试以及如何选择并运行测试。后一篇文章将讨论如何通过各种报告特性让测试支持更强大的技术。
Python 测试的黑暗时代
Python 项目测试曾经是非常特殊化、个人化的活动。开发人员可能先在单独的 Python 脚本中编写每组测试。然后,编写一个名为 test_all.py 或 tests.py 的脚本,这个脚本导入并运行他的所有测试。但是,无论这个过程的自动化做得多么好,这种方式仍然是特殊化的:参与项目的每个开发人员都必须知道测试脚本放在哪里以及如何调用它们。如果某个 Python 开发人员从事十几个项目,他必须记住十几个测试命令。
test_all.py(或项目采用的其他名称)还可能手工导入所有其他测试,这可能导致风险。如果这个集中的测试列表过时了(常常是由于开发人员添加了新的测试套件,手工运行它,但是忘了把它添加到中心脚本中),那么在 Python 包投入生产之前的后一次测试会遗漏许多测试。
这种无政府状态的另一个缺点是,它要求每个测试文件包含样板代码,从而能够作为单独的命令运行。如果查看 Python 文档或当今的一些 Python 项目,会看到许多这样的测试示例:
# test_old.py - The old way of doing things
import unittest
class TruthTest(unittest.TestCase):
def testTrue(self):
ass** True == 1
def testFalse(self):
ass** False == 0
if __name__ == '__main__':
unittest.main()
本系列的 第一篇文章 已经讨论过基于 TestCase 类的测试在现代环境中为什么常常是不必要的。但是,现在注意后两行:它们起什么作用?答案是,它们检测什么时候从命令行单独运行这个 test_old.py 脚本,在这种情况下,它们运行一个 unittest 简便函数,这个函数在模块中搜索测试并运行它们。它们使这个测试文件可以独立于项目范围的测试脚本单独运行。
显然,在数十甚至数百个测试模块中复制相同的代码非常麻烦。另一个不太明显的缺点是这种做法不利于标准化。如果 test_main() 函数不够完善,无法检测出某个模块的测试,那么这个模块的行为可能与其他测试套件不匹配。因此,每个模块在测试类的名称、操作方式和运行方式方面稍有差异。
Python 测试的开放时代
由于主流 Python 测试框架的出现,上述的所有问题已经解决了,而且每种框架解决这些问题的方式大致相同。
首先,这三种测试框架都提供了从操作系统命令行运行测试的标准方法。这样,每个 Python 项目不再需要在代码基中维护全局测试脚本。
zope.testing 包运行测试的机制是特殊化的:因为 Zope 开发人员常常使用 buildout 设置他们的项目,常常通过 buildout.cfg 文件中的 zc.recipe.testrunner recipe 安装测试脚本。但是,结果在不同的项目上相当一致:在我遇到的每个 Zope 项目中,开发 buildout 都会创建一个 ./bin/test 脚本,可以通过它调用项目的测试。
py.test 和 nose 项目的做法更意思。它们都提供一个命令行工具,所以每个项目完全不需要有自己的测试命令:
# Run "py.test" on the project
# in the current directory...
$ py.test
# Run "nose" on the project
# in the current directory...
$ nosetests
py.test 和 nosetests 工具甚至有几个相同的命令行选项,比如 -v 选项在执行测试时输出测试的名称。可能过不了多久,只要程序员熟悉这两种工具,能够运行大多数公共 Python 包的测试。
但是,还有后一级标准化!当今的大多数 Python 项目在源代码中包含一个 setup.py 文件,它支持下面的命令:
# Common commands supported by setup.py files
$ python setup.py build
$ python setup.py install
当今的许多 Python 项目使用 setuptools 包支持标准 Python 没有提供的 setup.py 命令,包括运行项目的所有测试的 test 命令:
# If a project's setup.py uses "setuptools"
# then it will provide a "test" command too
$ python setup.py test
这是标准化的高层次:如果项目都以一致的方式支持 setup.py test,开发人员可以通过统一的接口运行所有 Python 包的测试套件。nose 通过提供一个入口点支持 setup.py,这个入口点调用与 nosetests 命令相同的测试运行例程:
# A setup.py file that uses "nose" for testing
from setuptools import setup
setup(
# ...
# package metadata
# ...
setup_requires = ['nose'],
test_suite = 'nose.collector',
)
当然,即使项目提供了 setup.py 入口点,大多数开发人员可能仍然使用 nosetests,因为 nosetests 提供更强大的命令行选项。但是对于新的开发人员,如果只想在调试 bug 或添加新特性之前检查包是否能够在他的平台上工作,那么 test_suite 入口点是非常方便的。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11