技术开发 频道

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

  【IT168 技术】最近出现了行业级的 Python 测试框架,这意味着 Python 测试可以编写得更简洁、更统一,能够产生更好的结果报告。本文讨论先进的测试框架如何提供健壮的应用程序测试自动发现,以及这如何替代过去维护的集中式测试列表。

  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):
        assert
True == 1

    def testFalse(self):
        assert
False == 0

if __name__ == '__main__':
unittest.main()

  本系列的 第一篇文章 已经讨论过基于 TestCase 类的测试在现代环境中为什么常常是不必要的。但是,现在注意最后两行:它们起什么作用?答案是,它们检测什么时候从命令行单独运行这个 test_old.py 脚本,在这种情况下,它们运行一个 unittest 简便函数,这个函数在模块中搜索测试并运行它们。它们使这个测试文件可以独立于项目范围的测试脚本单独运行。

  显然,在数十甚至数百个测试模块中复制相同的代码非常麻烦。另一个不太明显的缺点是这种做法不利于标准化。如果 test_main() 函数不够完善,无法检测出某个模块的测试,那么这个模块的行为可能与其他测试套件不匹配。因此,每个模块在测试类的名称、操作方式和运行方式方面稍有差异。

0
相关文章