亲宝软件园·资讯

展开

python中更人性化的一个单元测试框架:nose2

王雨泽 人气:2

如果你学过 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 对于加深对测试框架的理解有很大的好处。

加载全部内容

相关教程
猜你喜欢
用户评论