聊聊 Python 的单元测试框架(二):nose 和它的继任者 nose2

作者:HelloGitHub-Prodesire
HelloGitHub 的《讲解开源项目》系列,项目地址:https://github.com/HelloGitHub-Team/Article
一、nose
nose 是一个第三方单元测试框架,它完全兼容 unittest,并且号称是一个更好用的测试框架。
那么 nose 除了具备 unittest 的所有功能外,还具有哪些优势呢?
1.1 用例编写
用例的编写方式除了编写继承于 unittest.TestCase 的测试类外,还可以编写成没有继承的测试类。比如,写成如下形式也会被 nose 视作一个测试类:
from nose.tools import raises
class TestStringMethods:
def test_upper(self):
assert 'foo'.upper() == 'FOO'
def test_isupper(self):
assert 'FOO'.isupper()
assert not 'Foo'.isupper()
@raises(TypeError)
def test_split(self):
s = 'hello world'
assert s.split() == ['hello', 'world']
# check that s.split fails when the separator is not a string
s.split(2)
当然,测试类并没有继承 unittest.TestCase,将不能使用其内置的各类 assertXXX 方法,进而导致用例出错时无法获得更加详细的上下文信息。
此外,nose 也支持定义函数来作为测试,这给许多简单的测试场景带来很大的便利:
def test_upper():
assert 'foo'.upper() == 'FOO'
1.2 用例发现和执行
unittest 所支持的用例发现和执行能力,nose 均支持。
nose 支持用例自动(递归)发现:
- 默认发现当前目录下所有包含
test的测试用例,但不包括以_开头的用例- 使用
nosetests命令
- 使用
- 通过
-w参数指定要自动发现的目录,-m参数指定用例文件、目录、函数、类的名称模式(正则匹配)nosetests -w project_directory "test_.+"
nose 也支持执行指定用例:
- 指定测试模块
nosetests test.module
- 指定测试类
nosetests a.test:TestCase
- 指定测试方法
nosetests another.test:TestCase.test_method
- 指定测试文件路径
nosetests /path/to/test/file.py
- 指定测试文件路径+测试类或测试函数(这是
unittest所不支持的)nosetests /path/to/test/file.py:TestCasenosetests /path/to/test/file.py:TestCase.test_methodnosetests /path/to/test/file.py:test_function
1.3 测试夹具(Fixtures)
nose 除了支持 unittest 所支持的定义测试前置和清理方式,还支持一种更为简单的定义方式:
def setup_func():
"set up test fixtures"
def teardown_func():
"tear down test fixtures"
@with_setup(setup_func, teardown_func)
def test():
"test ..."
只需定义两个函数用来表示前置和清理方法,通过 nose.tools.with_setup 装饰器装饰测试函数,nose 便会在执行测试用例前后分别执行所定义的前置和清理函数。
1.4 子测试/测试生成器
nose 除了支持 unittest 中的 TestCase.subTest,还支持一种更为强大的子测试编写方式,也就是 测试生成器(Test generators),通过 yield 实现。
在下面的示例中,定义一个 test_evens 测试函数,里面生成了 5 个子测试 check_even:
def test_evens():
for i in range(0, 5):
yield check_even, i, i*3
def check_even(n, nn):
assert n % 2 == 0 or nn % 2 == 0
此外,相较于 unittest.TestCase.subTest 多个子测试只能执行一次测试前置和清理,nose 的 测试生成器 可以支持每个子测试执行一次测试前置和清理,如:
def test_generator():
# ...
yield func, arg, arg # ...
@with_setup(setup_func, teardown_func)
def func(arg):
assert something_about(arg)
1.5 插件体系
nose 相较于 unittest 一个最大的优势就是插件体系,自带了很多有用的插件,也有丰富的第三方插件。这样就能做更多的事情。
其中,自带插件如下:
- AllModules:在所有模块中收集用例
- Attrib:给用例打标签,并可运行含指定标签的用例
- Capture:捕获用例的标准输出
- Collect:快速收集用例
- Cover:统计代码覆盖率
- Debug:用例失败时进入 pdb 调试
- Deprecated:标记用例为弃用
- Doctests:运行文档用例
- Failure Detail:断言失败时提供上下文信息
- Isolate:保护用例避免受一些副作用的影响
- Logcapture:捕捉 logging 输出
- Multiprocess:并行执行用例
- Prof:使用热点分析器进行分析
- Skip:标记用例为跳过
- Testid:为输出的每个用例名称添加测试 ID
- Xunit:以 xunit 格式输出测试结果
而第三方库则多种多样,如用来生成 HTML 格式测试报告的 nose-htmloutput 等,这里不再一一列出。
得益于 nose 丰富的插件生态,当 nose 本身不能够完全满足我们的测试需求时,可以通过安装插件,并在 nosetests 命令行指定该插件所提供的特定参数即可非常容易的使用插件。
相较于 unittest,就能省去很多自己开发额外测试逻辑的精力。
二、nose2
nose2 是 nose 的继任者。
它们的理念都是让编写和运行测试用例变得更容易。
它们有很多相同点,比如都兼容 unittest,支持使用函数作为测试用例,支持子测试,拥有插件体系。但也有很多不同点,下面列出一些主要的不同点:
- 发现和载入测试
nose自行实现了模块加载功能,使用惰性方式加载测试模块,加载一个执行一个。nose2则借助内建的 import() 导入模块,并且是先全部载入,再执行用例nose2并不支持nose所支持的所有测试用例项目结构,比如如下用例文件的结构在nose2中就不受支持:
.
`-- tests
|-- more_tests
| `-- test.py
`-- test.py
- 测试前置和清理函数级别
nose支持方法、类、模块和包级别的测试前置和清理函数nose2则不支持包级别的测试前置和清理函数
- 子测试
nose2除了支持使用测试生成器来实现子测试外,还支持使用参数化测试(Parameterized tests)来实现子测试nose2除了像nose一样支持在测试函数和测试类(不继承于unittest.TestCase)中支持参数化测试和测试生成器外,还支持在继承于unittest.TestCase的测试类中使用
- 配置化
nose期望所有插件的配置通过命令行参数进行配置nose2则通过配置文件进行控制,以最小化命令行参数让人读得更舒服
更多对比详见 官方文档。
三、小结
nose 和 nose2 在做到兼容 unittest 上就足以看出它们的目标,那便是要吸引原来那些使用 unittest 的用户来使用它们。它们确实做到了!
nose 和 nose2 在用例编写、测试夹具、子测试上做出改进,已经能让日常用例编写工作变得更加容易和灵活。同时又引入插件体系,进一步将单元测试框架的能力提升了一个大大的台阶,这让很多在基础测试功能之上的高阶功能的实现和共享成为了可能。也难怪有众多开发者对它们情有独钟。
『讲解开源项目系列』——让对开源项目感兴趣的人不再畏惧、让开源项目的发起者不再孤单。跟着我们的文章,你会发现编程的乐趣、使用和发现参与开源项目如此简单。欢迎留言联系我们、加入我们,让更多人爱上开源、贡献开源~
聊聊 Python 的单元测试框架(二):nose 和它的继任者 nose2的更多相关文章
- Python 单元测试框架系列:聊聊 Python 的单元测试框架(一):unittest
作者:HelloGitHub-Prodesire HelloGitHub 的<讲解开源项目>系列,项目地址:https://github.com/HelloGitHub-Team/Arti ...
- Python的单元测试(二)
title: Python的单元测试(二) date: 2015-03-04 19:08:20 categories: Python tags: [Python,单元测试] --- 在Python的单 ...
- Python自动单元测试框架
原文链接:http://www.ibm.com/developerworks/cn/linux/l-pyunit/ 软件的测试是一件非常乏味的事情,在测试别人编写的软件时尤其如此,程序员通常都只对编写 ...
- [转] Python自动单元测试框架
一.软件测试 大型软件系统的开发是一个很复杂的过程,其中因为人的因素而所产生的错误非常多,因此软件在开发过程必须要有相应的质量保证活动,而软件测试则是保证质量的关键措施.正像软件熵(software ...
- Appium+python的单元测试框架unittest(1)(转)
unittest为python语言自带的单元测试框架,python把unittest封装为一个标准模块封装在python开发包中.unittest中常用的类有:unittest.TestCase.un ...
- Appium+python的单元测试框架unittest(4)——断言(转)
(原文:https://www.cnblogs.com/fancy0158/p/10051576.html) 在我们编写的测试用例中,测试步骤和预期结果是必不可少的.当我们运行测试用例时,得到一个运行 ...
- 【Python】单元测试框架unitest及其高级应用
Unittest Unittest是python的一个单元测试框架,但是它不仅适用于单元测试,还适用自动化测试用例的开发与执行.我们可以很方便的使用它组织执行测试用例,使用它提供的丰富的断言方法进行测 ...
- Selenium(十六):unittest单元测试框架(二) 初识unittest(续)
1. 认识unittest(续) 关于unittest单元测试框架,还有一些问题值得进一步探讨.你可能在前一章的学习过程中产生了一些疑问,也许你会在本节中找到答案. 1.1 用例执行的顺序 用例的执行 ...
- python的单元测试框架
1.unittest是Python内置的标准类库.它的API跟Java的JUnit..net的NUnit,C++的CppUnit很相似. 通过继承unittest.TestCase来创建一个测试用 ...
随机推荐
- java面向对象中的集合
1.学习集合的原因? A.数组是面向过程的,集合是面向对象的. B.集合是类,具备类的封装,继承,多态...超强功能. C.数组是固定长度,集合是可变长度 D.数组没办法获得真实的元素个数:集合可以. ...
- JVM调优之经验
在生产系统中,高吞吐和低延迟一直都是JVM调优的最终目标,但这两者恰恰又是相悖的,鱼和熊掌不可兼得,所以在调优之前要清楚舍谁而取谁.一般计算任务和组件服务会偏向高吞吐,而web展示则偏向低延迟才会带来 ...
- Tomcat源码分析 (五)----- Tomcat 类加载器
在研究tomcat 类加载之前,我们复习一下或者说巩固一下java 默认的类加载器.楼主以前对类加载也是懵懵懂懂,借此机会,也好好复习一下. 楼主翻开了神书<深入理解Java虚拟机>第二版 ...
- Fabric项目学习总结
1.Hyperledger Fabric的基本架构 2.PKI机制
- linux下实现并发逻辑
################shell 模拟实现并发跑数#################有时候我们知道一些程序是可以同时跑的,互不影响,为了提高效率不得不使用并发跑脚本 #1.思路一我们都知道在 ...
- Python 面向導向語言 Object Oriented Programming Language
Pytho 是面向對象的程式語言,舉凡 Literals 值都是 Object.例如: >>> id(38)8791423739696 與 >>> id('ABC' ...
- Python 标识符说明
在Python中,标识符有字母.数字.下划线组成 所有标识符都可以包括英文.数字.下划线,但不能以数字开头 Python标识符区分大小写 ※以下划线开头的标识符有特殊含义. 例如:以单下划线开头(_t ...
- NN入门,手把手教你用Numpy手撕NN(一)
前言 这是一篇包含极少数学推导的NN入门文章 大概从今年4月份起就想着学一学NN,但是无奈平时时间不多,而且空闲时间都拿去做比赛或是看动漫去了,所以一拖再拖,直到这8月份才正式开始NN的学习. 这篇文 ...
- node.js的Promise对象的使用
Promise对象是干嘛用的? 将异步操作以同步操作的流程表达出来 一.Promise对象的定义 let flag = true; const hello = new Promise(function ...
- PIXIJS的一些使用
我发现pixijs在国内简直就是一片静土啊,只有那么一点点的微弱的不能再微弱的声音. 我在这里整理了下我使用过程中解决和可能理解的一些问题吧,都是一个个点,而不是完整的示例. 先放官网示例: http ...