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

发表于:2021-5-25 09:23

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:佚名    来源:掘金

  一、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:TestCase
  nosetests /path/to/test/file.py:TestCase.test_method
  nosetests /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,就能省去很多自己开发额外测试逻辑的精力。

      本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号