如何覆盖鼻子的拆解功能?

时间:2018-01-03 08:53:23

标签: python unit-testing nose

使用nosetest进行测试时,每个测试用例的结果可能是“成功”,“失败”或“错误”。这被写成STDOUT为'。','F'和'E'。

  • ˚F
  • 电子

有没有办法覆盖此功能并打印出其他调试信息?

附录

根据下面给出的信息,我创建了以下测试代码:

from nose.tools import assert_true
from nose.plugins import Plugin

class Tester(Plugin):

    def addSuccess(self, test):
        print("Test successful")

    def addError(self, test, err):
        print("Had error: %s" % err)

    def addFailure(self, test, err):
        print("Had failure: %s" % err)


class TestSuite(object):
    def test1(self):
        assert_true(True)

但是,当我使用

运行此示例测试时,不会生成其他输出
nosetests --nologcapture -s test1.py 

我是否需要以某种方式“注册”该插件?

Addendum2:

我创建了一个文件plugin1.py,内容如下:

import os
from nose.plugins import Plugin

class Plugin1(Plugin):
    def addSuccess(self, test):
        print("Test successful")

    def addError(self, test, err):
        print("Had error: %s" % err)

    def addFailure(self, test, err):
        print("Had failure: %s" % err)

    def options(self, parser, env=os.environ):
        super(Plugin1, self).options(parser, env=env)

    def configure(self, options, conf):
        super(Plugin1, self).configure(options, conf)

和测试脚本如下(test1.py):

from nose.tools import assert_true


class TestSuite(object):
    def test1(self):
        assert_true(True)


import nose
from plugin1 import Plugin1

if __name__ == '__main__':
    nose.main(addplugins=[Plugin1()])

但我仍然得到同样的结果。我想我必须以其他方式“注册”这个插件。但是怎么样?关于这一点的documentation几乎不存在......

通过

运行整个测试
python test1.py

产生相同的输出,但不产生plugin1.py中给出的附加文本输出。

1 个答案:

答案 0 :(得分:4)

您可以使用nose plug-in framework执行此操作。基本上,您的插件需要提供addError方法,该方法在测试错误时被调用。该方法获取传入的测试用例,您应该能够自省错误并在那里记录额外的调试信息。请查看TestTextResultResultProxy类。

示例包含一个完整的插件,可以将输出流(HTMLPlugin)修改为html格式。

<强>更新

文档确实非常糟糕。这就是我拼凑的东西。

import sys
from nose.tools import assert_true
import nose
from nose.plugins import Plugin

class Plugin1(Plugin):
    def __init__(self):
        self.reports = []
        # self.name = 'mega-plugin'
        super(Plugin1, self).__init__()

    def addSuccess(self, test):
        print('Test successful')
        self.reports.append("Test successful")
        self.stream.writeln("Test successful")

    def setOutputStream(self, stream):
        self.stream = stream
        return None

    def finalize(self, result):
        for t in self.reports:
            self.stream.writeln('finalize - ' + t)

class TestSuite(object):
    def test1(self):
        assert_true(True)


if __name__ == '__main__':
    nose.main(argv=sys.argv + ['--with-plugin1'], addplugins=[Plugin1()])

该输出是

Test successful
.
----------------------------------------------------------------------
Ran 1 test in 0.003s

OK
finalize - Test successful

有几点意见:

  1. 仅使用addplugins 注册它未启用它的插件
  2. 您必须指定--with-PLUGIN-NAME才能实际使用
  3. --with-PLUGIN-NAME不能在argv中排在第一位,因为传统上它是程序名称
  4. 插件从类名和自动--with-PLUGIN-NAME标志中获取自动名称,您可以覆盖名称,也可以覆盖--with-SOMETHING标志。
  5. 如果您想在测试运行期间打印到stderr,则还必须指定--nocapture,否则nose将阻止标准输出(请注意来自{print addSuccess 1}}未显示在输出中)
  6. 您应该实现setOutputStream方法并存储对输出流的本地引用,或者在__init__期间设置您自己的输出流。
  7. 如果您有setOutputStream方法并且从中返回None,则其他插件可以使用相同的流。您可以返回虚拟流以禁止默认输出(https://nose.readthedocs.io/en/latest/plugins/writing.html#recipes
  8. 为了保证一切都干净整洁,你还应该实现一个finalize方法,只在那里打印输出,而不是在测试运行时 - addSuccesaddFailure等被调用在测试期间,所有测试完成后都会调用finalize
  9. 所有这一切都应该在文档中。