python中更人性化的一个单元测试框架:nose2
如果你学过 python 进行自动化测试,你一定使用过 unittest。今天我们要讲的 nose2 是一个高级版本的 unittest。他比 unittest 更容易理解,用起来也更加方便一些。
快速开始
nose2 在 unittest 的基础上开发的,所以如果你之前是用 unittest 做测试,但是有想使用 nose2 的新特性,你可以在不改变原有代码的情况下直接使用 nose2。
import unittest
import nose2
class TestAdd(unittest.TestCase):
def test_add(self):
self.assertEqual(1+1, 3)
if __name__ == '__main__':
# 只需要替换这一行
# unittest.main()
nose2.main()
安装
nose2 是第三方库,需要自己安装,直接在 cmd 运行 pip 指令安装:
pip install nose2
运行测试用例
在快速开始当中,我们使用了在 python 代码中用 nose2.main() 的方式去运行测试用例,这样是完全 OK 的。
还有另外一种运行方式:直接在命令行通过 nose2 命令运行。他会在python文件中查找名称以 test 开头的测试文件,并运行它发现的每个以 test 开头的测试函数名称。比如说我的项目当中有 test_add.py, test_minus.py 这些文件,如果我想运行所有的测试用例,只需要在当前文件下输入 cmd 命令,他就会自动去查找所有的测试用例,然后去执行:
nose2
运行指定文件夹下的测试用例
nose2 -s 文件夹名称
我把登录相关的用例都放到一个叫 login_case 的文件夹当中,当我执行 nose2 -s login_case
的时候,其他的用例是不会执行的, nose2 只会去找 login_case 文件夹下面的用例。
运行指定的测试用例
nose2 login_case.test_nose2_dir.test_login
在这个例子当中:
- login_case 是存储的文件夹
- test_nose2_dir 是文件名称
- test_login 是测试用例方法的名称
每一个层级之间,用 .
号隔开。
如果想测试 test_nose2_dir.py 文件下的所有用例:
nose2 login_case.test_nose2_dir
如果想测试 login_case 文件夹下的所有用例:
nose2 login_case
测试用例的命名
为什么 nose2 可以自动查找用例并且执行呢?是因为他在内部制定了规则,然后根据规则去判定。
比如首先他规定,你所有的测试用例文件名称应该以 test 开头,如果你不这么做,那这个文件就不是测试用例文件。以下的文件名都会被判定为测试用例文件:
test.py
test_add.py
testRegister.py
而这一些不会被判定为测试用例文件,从而被忽略:
add_test.py
a_test.py
register_test_file.py
高级特性
测试用例方法的编写
与unittest不同的是,nose2 的测试用例并不一定要以类的形式存在,也可以使用函数。任何函数和类,只要名称匹配一定的条件(例如,以test开头或以test结尾等),都会被自动识别为测试用例。
def test_add():
assert 1 == 2
if __name__ == '__main__':
nose2.main()
参数化
类似于 unittest 当中的 ddt 模块,不过比 ddt 模块使用起来简洁一些。在测试过程当中,通常会有多组测试用例数据,多组测试用例会共用一个测试用例的方法,从而实现数据驱动。在 nose2 当中你可以这样使用:
import nose2
from nose2.tools import params
def add(a, b):
return a + b
test_data = [
{"data": (1, 2), "expected": 3},
{"data": (2, 2), "expected": 4},
{"data": (3, 2), "expected": 6},
]
@params(*test_data)
def test_add(data):
assert add(*data["data"]) == data["expected"]
1, @params(*test_data)
会接收外部传进来的多组测试数据;
2,test_add(data)
当中的 data 每次取出一组数据运行,所以,data 其实就是 {“data”: (1, 2), “expected”: 3} 这样的一组数据。
3,这里因为有 3 组数据,所以运行的时候会有 3 个测试用例。
测试夹具
测试夹具是为了给测试用例准备前置条件和后置条件。
- @with_setup(before_test) 表示在测试用例执行之前要执行的前置条件
- @with_teardown(after_test) 表示在测试用例执行之后的后置条件
- before_test 和 after_test 是自己定义的函数
from nose2.tools.decorators import with_setup, with_teardown
def before_test():
print("before test")
def after_test():
print("after test")
@with_setup(before_test)
@with_teardown(after_test)
def test_add(data):
assert add(*data["data"]) == data["expected"]
总结
本篇我们介绍了 nose2 的简单入门:
- nose2 是在 unittest 的基础上实现的,可以和 unittest 兼容,如果你没有接触过 unittest, 建议先从 unittest 学起,很多同学在网上看到一些说 unittest 过时或者是说 unittest 不高级的言论就开始批判,不对。 unittest 是 其他 python 单元测试框架的基础,没学好 unittest , 其他的框架你也学不好。
- nose2 可以自动发现测试用例,你只需要运行 nose2 命令就可以,用起来非常简单。
- nose2 的测试用例名称要符合规范,以 test 开头,否则不会被判定为用例。
- 你可以通过
-s
运行指定文件下的用例,也可以通过.
号去运行单个用例。
nose2 vs unittest
nose2 上手会比 unittest 更简单,使用 unittest, 需要同时掌握 testrunner, testsuite, testcase 等基本概念,还需要熟悉类和对象。 nose2 隐藏了这些细节设计,难度会更低一些。
nose2 可以直接运行 unittest 的测试用例,可以实现无缝切换。
但是并不是说 unittest 就不好。 unittest 做为一个 python 标准库,和 python 版本绑定,非常稳定,不用担心兼容性的问题。
如果要学习一个单元测试框架,建议从 unittest 开始,因为你可以接触到 loader, suite, runner 这样的组件,对理解测试框架更有帮助,学习好 unittest 以后,再学习 nose2 或者 pytest 这样更高级的框架,能有效提升编程效率。
nose2 vs pytest
如果你只想学习一个高级单元测试框架,建议你学 pytest, 而不是 nose2。
nose2 足够好,甚至看上去他的设计比 pytest 更加清晰,更容易理解。但是社区没有 pytest 活跃,因此使用的人也比较少。
实际上,nose2 和 pytest 的用法很多都是非常类似的,学习了一个,另外一个也能轻松上手。nose2 对于加深对测试框架的理解有很大的好处。
python中更人性化的一个单元测试框架:nose2的更多相关文章
- Python+selenium之简单介绍unittest单元测试框架
Python+selenium之简单介绍unittest单元测试框架 一.unittest简单介绍 unittest支持测试自动化,共享测试用例中的初始化和关闭退出代码,在unittest中最小单元是 ...
- python模块详解 | unittest(单元测试框架)(持续更新中)
目录: why unittest? unittest的四个重要概念 加载测试用例的三个方法 自动加载测试用例 忽略测试和预期失败 生成html测试报告 why unittest? 简介: Unitte ...
- [译]Python中的异步IO:一个完整的演练
原文:Async IO in Python: A Complete Walkthrough 原文作者: Brad Solomon 原文发布时间:2019年1月16日 翻译:Tacey Wong 翻译时 ...
- 用Python手把手教你搭建一个web框架-flask微框架!
在之前的文章当中,小编已经教过大家怎么搭建一个Django框架,今天我们来探索另外的一种框架的搭建,这个框架就是web框架-flask微框架啦!首先我们带着以下的几个问题来阅读本文: 1.flask是 ...
- Python+Selenium学习笔记16 - unittest单元测试框架
unittest单元测试框架包括 Test Case, Test Suite, Test Runner, Test Fixture Test Cases 组成Test Suite, Test Run ...
- Python中Template使用的一个小技巧
Python中Template是string中的一个类,可以将字符串的格式固定下来,重复利用. from string import Template s = Template("there ...
- Python 中更优雅的日志记录方案
在 Python 中,一般情况下我们可能直接用自带的 logging 模块来记录日志,包括我之前的时候也是一样.在使用时我们需要配置一些 Handler.Formatter 来进行一些处理,比如把日志 ...
- python中错误、调试、单元测试、文档测试
错误分为程序的错误和由用户错误的输入引起的错误,此外还有因为各种各样意外的情况导致的错误,比如在磁盘满的时候写入.从网络爬取东西的时候,网络断了.这类错误称为异常 错误处理 普通的错误处理机制就是在出 ...
- 使用Python中的mock模块进行单元测试
在进行单元测试的时候,有时候会遇到这种情况: 出于某些原因,我们不想测试某一部分内容,但是我们想要测试的部分却依赖这部分内容. 这时候,可以使用mock模块来模拟调用这部分内容,并给出返回结果,举例如 ...
随机推荐
- 日期格式化使用 YYYY-MM-dd 的潜在问题
昨天在v站上看到这个关于YYYY-MM-dd的使用而出现Bug的帖子(v2ex.com/t/633650)非常有意思,所以拿过来分享一下. 在任何编程语言中,对于时间.数字等数据上,都存在很多类似这种 ...
- Python 打包——过去、现在与未来
英文 | Python packaging - Past, Present, Future[1] 原作 | BERNAT GABOR 译者 | 豌豆花下猫 声明 :本文获得原作者授权翻译,转载请保留原 ...
- 双系统,重装windows 无法进入Windows安装界面
解决办法 windows引导并没有被更新 进入linux 更新grub sudo update-grub 然后重启电脑,进行下一步安装 原理 grub是引导操作系统的程序,它会根据自己的配置文件,去引 ...
- Django ORM调优实践
一.分析请求慢响应的主要原因 将请求执行的任务按功能分为几块,用time.time()打印每个模块的执行时间,大部分情况下性能会主要消耗在某一个模块上,即80%的性能问题是出在20%的代码上 找到主要 ...
- 吴恩达机器学习笔记 - cost function and gradient descent
一.简介 cost fuction是用来判断机器预算值和实际值得误差,一般来说训练机器学习的目的就是希望将这个cost function减到最小.本文会介绍如何找到这个最小值. 二.线性回归的cost ...
- Could not find a version that satisfies the requirement numpy>=1.7.0 (from pan das==0.17.0) (from versions: ) No matching distribution found for numpy>=1.7.0 (from pandas==0.17.0)
今天晚上一直在安装pandas,天杀的,真的是太难了.后来发现提示: Could not find a version that satisfies the requirement numpy> ...
- Celery 收下这捆芹菜!
目录 Celery简介 Celery构成 Task Broker Worker Backend Celery使用 安装 基本使用 异步任务: delay 延迟任务: apply_async 周期任务: ...
- 基于 HTML5 + WebGL 的 3D 风力发电场
前言 风能是一种开发中的洁净能源,它取之不尽.用之不竭.当然,建风力发电场首先应考虑气象条件和社会自然条件.近年来,我国海上和陆上风电发展迅猛.海水.陆地为我们的风力发电提供了很好地质保障.正是 ...
- 趣谈编程史第2期-这个世界缺少对C语言的敬畏,你不了解的C语言科普
这是我制作的编程语言科普系列视频的第二期,博客根据视频文案整理而成,提供给有需要的朋友阅读或使用. 视频地址:https://www.bilibili.com/video/av83627932/ ...
- doT的高级用法及loadData的使用
本文出自APICloud官方论坛, 感谢论坛版主 gp3098的分享. 之前直接把模板写在页面底部的script标签内的,但是现在不同. 使用了doT.js配合api的loadData方法,整个页面就 ...