微信号:grzlwx

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

用 Python 测试框架简化测试 (续)

2015-08-17 21:18 光荣之路


框架特有的约定

py.test和nose框架都提供特殊的例程,这些例程可以简化测试的编写。可以认为它们分别提供一种方便的测试“方言”,可以用这些“方言”编写测试。这会简化测试的编写并减少错误,还会使测试更简短、可读性更好。但是,使用这些例程还会导致一个重要的后果:您的测试与提供函数的框架捆绑在一起了,丧失了兼容性。

因此,要权衡考虑方便性和兼容性。如果只使用笨拙的标准Python unittest模块从头编写所有测试,那么它们能够在任何测试框架中运行。更进一步,如果采用简单的做法编写测试函数(如上所述),那么测试至少能够在py.test和nose中运行。但是,如果开始使用某个测试框架特有的特性,那么如果以后另一个框架开发出了新的重要特性,您决定进行框架迁移,就必须重写测试。

py.test和nose都为TestCase的assertRaises()方法提供了替代品。py.test提供的版本比较新颖,它也可以接受要执行的字符串,这更强大,因为可以测试引发异常的表达式,而不只是函数调用:

# conveniences.py import math import py.test py.test.raises(OverflowError, math.log, 0) py.test.raises(ValueError, math.sqrt, -1) py.test.raises(ZeroDivisionError, "1 / 0") import nose.tools nose.tools.assert_raises(OverflowError, math.log, 0) nose.tools.assert_raises(ValueError, math.sqrt, -1) # No equivalent for third example!

但是,除了都能够测试异常之外,这两种框架的差异就比较大了。py.test 只提供一个简便函数,它用来判断特定调用是否会触发 DeprecationWarning

py.test.deprecated_call(my.old.function, arg1, arg2)

另一方面,nose 提供非常丰富的断言函数,适用于希望避免 assert 语句和需要进行比较复杂的测试的情况。详细信息请参考它的文档,下面列出 nose 提供的断言函数:

# nose.tools support functions for writing tests assert_almost_equal(first, second, places=7, msg=None) assert_almost_equals(first, second, places=7, msg=None) assert_equal(first, second, msg=None) assert_equals(first, second, msg=None) assert_false(expr, msg=None) assert_not_almost_equal(first, second, places=7, msg=None) assert_not_almost_equals(first, second, places=7, msg=None) assert_not_equal(first, second, msg=None) assert_not_equals(first, second, msg=None) assert_true(expr, msg=None) eq_(a, b, msg=None) ok_(expr, msg=None)

在处理浮点数时,如果希望测试能够灵活地对待 Python 实现,允许对浮点数的处理有细小的误差,那么上面检查近似值的例程尤其有意义。

分布式测试

目前,测试的运行频率越来越高了。许多团队已经采用了连续测试,也就是对团队版本控制系统的每次签入(check-in)都要运行项目测试。随着测试驱动开发方法越来越流行,许多开发人员在开始编写新模块的代码之前先为模块编写和运行测试。如果测试的运行时间很长,就会严重影响开发人员的生产力。

因此,用尽可能多的计算能力运行测试是很有益处的。对于小规模项目,这可能意味着使用计算机的所有CPU核运行多个测试进程。对于更大的项目,要配置完整的测试计算机群,要么使用专用服务器并行地运行测试,要么使用所有开发人员工作站的空闲时间。

在并行和分布式测试方面,本文讨论的三种测试框架有非常显著的差异:

  • zope.testing 命令行有一个 -j 选项,它指定应该启动多个测试进程,而不是在同一进程中执行所有测试。因为每个进程可以在不同的 CPU 核上运行,所以如果在有四个 CPU 的计算机上运行 -j 4,就可以同时用四个 CPU 运行测试。

  • nose 项目报告说,他们已经把对并行测试的支持提交到项目 trunk,但是一般用户要等到下一个版本才能试用这个特性。

  • py.test 工具支持一个多处理选项 (-n),可以像 zope.testing 一样在多个 CPU 核上运行测试。另外,它还提供管理工具,可以在整个测试服务器群中分布测试。

在这三种框架中,py.test 看起来在并行测试方面明显领先了。可以指定多个 --tx 选项,每个选项描述要运行测试的一个环境或远程服务器。而且,它实际上支持针对两个完全不同的原因分布测试!在使用 --dist=load 时,它将使用服务器群按照传统方式在多台计算机上运行测试,从而减少测试花费的时间。但是,在使用 dist=each 时,它的做法就比较复杂了;它确保每个测试在 py.test 可用的每个测试环境中运行。

这意味着 py.test 可以同时在多个 Python 解释器版本和多个操作系统上运行测试。因此,如果项目支持多个平台,希望测试解决方案能够自动地支持多平台,而不需要通过编写脚本把测试复制到不同的平台并运行它们,那么 py.test 的这个特性是非常吸引人的。

定制和可扩展性

这三种测试框架都为单独的用户和整个项目提供定制能力,可以根据需要选择测试框架的行为和选项。

  • 在 Zope 包中,指定默认选项的 buildout 常常调用 zope.testing 模块。这意味着运行测试的开发人员会得到统一的结果集。但是,如果在项目级上选择的行为无法满足他们的需要,他们仍然可以指定自己的命令行开关。

  • nose 框架通过用户主目录中的 nose.cfg.noserc 文件支持用户个性化定制,用户可以在这些文件中指定测试结果的显示方式。

  • 对于 py.testnose 框架,都可以提供针对整个项目的选项。py.test 框架会在它测试的项目中寻找 conftest.py 文件,然后在这个文件中寻找针对整个项目的选项,比如是否检测并运行 doctest 以及应该使用哪种模式检测测试文件和函数。nose 框架寻找项目范围的 setup.cfg 文件(这是提供 Python 包的相关信息的标准方式),然后在其中寻找 [nosetests] 节。

另外,py.testnose 都支持插件,这些用户提供的模块可以安装新的命令行选项和在工具中添加新行为,但是它们提供的配置和能够实现的功能有差异。

结束语

在过去,每个 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第二讲 推荐本好书《与机器赛跑》
猜您喜欢 Python奇技淫巧 动态规划:从新手到专家 数据库系列教程六:数据库事务 敏捷破冰之旅(三) 想要愉快入住酒店?缺了它还真不行!