Nose没有运行示例插件中的add *方法

时间:2015-08-10 16:26:39

标签: python nose

我正在尝试学习一些关于编写鼻子插件的知识,所以我采用了他们的示例HtmlOutput插件,我试图像这样使用它:

import unittest
import nose
import sys
import traceback

class MyTest(unittest.TestCase):
    def test_failing(self):
        self.assertTrue(False)

    def test_passing(self):
        self.assertTrue(True)

class HtmlOutput(nose.plugins.Plugin):
    """Output test results as ugly, unstyled html.
    """
    name = 'html-output'
    score = 2 # run late

    def __init__(self):
        super(HtmlOutput, self).__init__()
        self.html = [ '<html><head>',
                      '<title>Test output</title>',
                      '</head><body>' ]

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

        self.enabled = True

    def addSuccess(self, test):
        self.html.append('<span>ok</span>')

    def addError(self, test, err):
        err = self.formatErr(err)
        self.html.append('<span>ERROR</span>')
        self.html.append('<pre>%s</pre>' % err)

    def addFailure(self, test, err):
        err = self.formatErr(err)
        self.html.append('<span>FAIL</span>')
        self.html.append('<pre>%s</pre>' % err)

    def finalize(self, result):
        self.html.append('<div>')
        self.html.append("Ran %d test%s" %
                         (result.testsRun, result.testsRun != 1 and "s" or ""))
        self.html.append('</div>')
        self.html.append('<div>')
        if not result.wasSuccessful():
            self.html.extend(['<span>FAILED ( ',
                              'failures=%d ' % len(result.failures),
                              'errors=%d' % len(result.errors),
                              ')</span>'])
        else:
            self.html.append('OK')
        self.html.append('</div></body></html>')
        # print >> sys.stderr, self.html
        for l in self.html:
            self.stream.writeln(l)

    def formatErr(self, err):
        exctype, value, tb = err
        return ''.join(traceback.format_exception(exctype, value, tb))

    def setOutputStream(self, stream):
        # grab for own use
        self.stream = stream
        # return dummy stream
        class dummy:
            def write(self, *arg):
                pass
            def writeln(self, *arg):
                pass
        d = dummy()
        return d

    def startContext(self, ctx):
        try:
            n = ctx.__name__
        except AttributeError:
            n = str(ctx).replace('<', '').replace('>', '')
        self.html.extend(['<fieldset>', '<legend>', n, '</legend>'])
        try:
            path = ctx.__file__.replace('.pyc', '.py')
            self.html.extend(['<div>', path, '</div>'])
        except AttributeError:
            pass

    def stopContext(self, ctx):
        self.html.append('</fieldset>')

    def startTest(self, test):
        self.html.extend([ '<div><span>',
                           test.shortDescription() or str(test),
                           '</span>' ])

    def stopTest(self, test):
        self.html.append('</div>')

suite  = unittest.defaultTestLoader.loadTestsFromTestCase(MyTest)
nose.run(argv=['-s'],
         suite=suite,
         addplugins=[HtmlOutput()])

该插件似乎实际初始化,所以我得到了这个输出:

<html><head>
<title>Test output</title>
</head><body>
<div>
Ran 2 tests
</div>
<div>
<span>FAILED (
failures=1
errors=0
)</span>
</div></body></html>

我遇到的问题是该插件似乎完全跳过了addFailureaddSuccessaddError方法,我无法找到跳过它的任何理由它们。

1 个答案:

答案 0 :(得分:0)

今天进行了额外的研究后,我在鼻子回购中遇到了this GitHub issue

问题是unittest.defaultTestLoader.loadTestsFromTestCase(MyTest)实际上确实返回TestSuite,而suite选项似乎实际上需要一个测试列表。幸运的是,解决我的问题就像执行suite._tests一样简单,addFailure等挂钩工作正常。