微信号:grzlwx

介绍:光荣之路官方资讯

用 Python 测试框架简化测试

2015-08-16 21:27 光荣之路



Python 测试领域的蛮荒时代结束了。仅仅在几年前,几乎每个用 Python构建的项目在编写和运行测试方面都采用自己的习惯做法。但是现在,这种混乱局面终于要结束了。社区中已经出现了几种出色的测试解决方案,它们为数百个流行的项目的测试套件提供约定和通用标准。

本文是 三篇系列文章 的第一篇,本系列要介绍新的测试框架。在本文中,将介绍三种流行的测试框架,讨论新一代工具鼓励的简单测试风格。第二篇文章发现和选择测试 讨论更大的问题:这些框架如何自动地发现和分类项目的测试。最后一篇文章用 Python 测试框架生成测试报告 讨论这些框架为查看测试结果提供的强大特性。

通过学习这三种框架的通用习惯做法,您不但可以更好地理解其他程序员编写的 Python 包,还可以为自己的应用程序构建优雅、强大的测试套件。

候选框架:三种 Python 测试框架

有三种 Python 测试框架是目前使用最为广泛的。下面按时间次序简要介绍它们:

  • zope.testing

    通常,从事 Zope 项目的开发人员就像是早期的拓荒者。他们需要以一种统一的方式在大型代码基上发现和运行测试,为此开发了 zope.testing 包,这个包现在仍然得到广泛使用。

    zope.testing 包只支持 unittestdoctest 等传统 Python 测试风格,而不支持更现代的框架支持的简化风格。但是,它提供一个强大的分层系统,在这种系统中包含测试的目录可以依赖于通用的设置代码,设置代码为层(而不是每个测试)创建一个运行测试所需的环境。

  • py.test

    2004 年,Holger Krekel 把他的 std 包改名为 ‘py’,因为原来的名称常常与 Python 附带的标准库混淆。尽管这个包包含另外几个子包,但是现在最著名的部分只有它的 py.test 框架。

    py.test 框架建立了 Python 测试的新标准,目前许多开发人员都采用这种标准。它为编写测试提供了优雅的符合 Python 风格的习惯做法,让开发人员能够以非常紧凑的风格编写测试套件。

  • nose

    nose 项目是于 2005 年发布的,也就是 py.test 改名后的一年。它是由 Jason Pellerin 编写的,支持与 py.test 相同的测试习惯做法,但是这个包更容易安装和维护。尽管 py.test 在某些方面有所进步,目前也很容易安装,但是 nose 仍然保持了易用性方面的声誉。

    在 Python 大会上,常常会看到开发人员穿着黑色 T 恤衫,上面印着 nosetests 命令,后面是表示测试成功的点号。有意思的是,随着 nose 的发展,在项目邮件列表上常常看到开发人员向项目负责人询问他们的项目什么时候可以转换到 nose

在这三种框架中,nose 看起来会成为标准,py.test 的用户群比较小,但是很忠诚,zope.testing 只在基于 Zope 框架的项目中受欢迎。但是,这三种框架都得到积极的维护,各有一些独特的特性。建议您了解它们的特性和差异,选择适合自己项目的框架。

测试演化

py.test 框架接受普通的 Python 函数作为测试,而不要求把测试放在更大更重型的测试类中,这开启了 Python 测试的新时代。因为 nose 框架支持相同的习惯做法,所以这些模式很可能越来越流行。

假设希望检查 Python 真假值 TrueFalse 是否真的等于布尔数字 10py.testnose 接受并运行以下代码行,作为回答此问题的有效测试:

# test_new.py - simple tests functions def testTrue(self): assert True == 1 def testFalse(self): assert False == 0

为了体会以上示例的简单性,可以对比过去的 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()

看到了吗?这么多代码只是为了支持两行测试代码!首先,代码需要一个 import 语句,这与要测试的代码完全无关,因为测试本身简单地忽略模块,只使用内置的 Python 值,比如 TrueFalse。另外,要创建一个类,但是它不支持或增强测试,因为测试实际上没有使用它们的 self 参数做任何事情。最后,需要两行固定不变的代码,这样才能从命令行运行这个测试。

有使用 unittest 经验的用户可能认为,上面的示例应该使用 TruthTest 类从 TestCase 类继承的测试方法。例如,他们会建议使用 assertEqual(),而不是手工测试是否相等的 assert 语句,在这种情况下测试会使用 self 而不是忽略它:

# alternate version of the TestTrue method ... def testTrue(self): self.assertEqual(True, 1) ...

对这个建议有三条反对意见。

首先,调用方法会影响可读性。尽管 assertEqual() 方法名能够表明要测试两个值是否相等,但是代码看起来仍然不像是比较,对于熟悉 Python 语言的开发人员,不如 Python == 操作符那么明确。

第二,正如在本系列的第三篇文章中将看到的,新的测试框架现在知道如何检查 assert 语句,从而查明造成测试失败的条件,这意味着简单的 assert 语句现在能够产生有意义的测试失败消息,它提供的信息与调用 assertEqual() 等老方法的结果差不多。

最后,即使 assertEqual() 仍然是必要的,但是从测试模块导入这个函数(而不是通过类继承让函数可用)肯定更简单,更符合 Python 的风格。实际上,在下面会看到,当 py.testnose 要提供更多用来支持测试的例程时,它们只需把这些例程定义为函数,然后用户可以把这些函数导入自己的代码。

当然,如果作者确实需要通过例程缓存状态,以便以后在测试用例中使用,unittest 子类仍然是有意义的,py.testnose 完全支持它们。另外,目前许多 Python 测试编写为 Python 标准库支持的 doctest,它们不需要使用函数或类:

Doctest For The Above Example ----------------------------- The truth values in Python, named "True" and "False", are equivalent to the Boolean numbers one and zero. >>> True == 1 True >>> False == 0 True

但是,如果程序员希望编写简单的测试代码,不愿意考虑doctest涉及的乱七八糟的东西,那么测试函数是很好的方法。总之,测试函数可以极大地增强编写测试的简便性。程序员不需要记住、重写或复制以前编写的测试代码,新的约定让 Python 程序员能够像编写一般 Python 代码一样编写测试:只需打开一个空文件,然后输入!

(未完待续)

(作者:Brandon Craig Rhodes 来源:http://www.ibm.com/developerworks/cn/aix/library/au-python_test/)


 
            
 
            
 
            
 
           
 
           
 
           
 
           
 
           
 
           
 
           
 
           
 
           
 
           

一字一句当思来之不易,感谢作者,传播测试知识、技能与正能量!

光荣之路软件测试培训

官网:http://www.gloryroad.cn/

微信公众号:gloryroadtrain

性能测试QQ群:415987441
软件测试招聘QQ群: 203715128
自动化3群QQ: 371211499


 
光荣之路 更多文章 今天晚上的 linux 公开课- Awk 编程 7月28日(今天)晚上的 linux 公开课- shell编程 8月4日(今天)晚上的 linux 公开课- shell编程 9月1日(本周一)晚8点半,光荣之路Web自动化系列基础课—javascript第二讲 推荐本好书《与机器赛跑》
猜您喜欢 FPGA:下一代机器人感知处理器 那些年你面试过的奇葩 总结2015,展望2016 公众号的相关说明 代码不再重要,未来我们要像训狗一样训练计算机