我如何使用unittest.TestResult?

时间:2015-10-03 07:24:24

标签: python unit-testing jython

我只是在短时间内使用unittest。我正在使用Jython 2.7.10“最终版本”

在解释TestResult的Python 2.7文档中,它说:

  

TestResult类的以下方法用于维护   内部数据结构,可以在子类中扩展以支持   额外的报告要求。这在特别有用   构建工具,在测试时支持交互式报告   正在运行。

     

startTest(test)... stopTest(test)... startTestRun()... stopTestRun()¶

这就是我想要做的......但我无法弄清楚你如何使用TestResult。这是一个SSCCE ......

import unittest

class TestResultX( unittest.TestResult ):
    def startTest( self, test ):
        print( '# blip')
        unittest.TestResult.startTest( self, test )
    def stopTest( self, test ):
        print( '# blop')
        unittest.TestResult.stopTest( self, test )
    def startTestRun( self ):
        print( '# blep')
        unittest.TestResult.startTestRun( self )
    def stopTestRun( self ):
        print( '# blap')
        unittest.TestResult.stopTestRun( self )

class TestCaseX( unittest.TestCase ):
    def test_nonsense(self):
        print( '# wotcha' )
        self.assertTrue( False )

    def run( self, test_result=None ):
        print( '# spoons starting...')

        test_result = TestResultX()
        unittest.TestCase.run( self, test_result )

        print( '# ...spoons ended, tr %s' % ( test_result,  ) )

unittest.main()

结果:

# spoons starting...

----------------------------------------------------------------------
Ran 0 tests in 0.015s

OK
# blip
# wotcha
# blop
# ...spoons ended, tr <__main__.TestResultX run=1 errors=0 failures=1>

问题:

  • 为什么会说0 tests
  • 为什么不打印blepblap(运行的开始和结束)?

更一般地说:

  1. 当谈到TestResult,TestRunner,TestLoader等时,有人可能指向一本好的教程/书籍解释“正确使用”/“良好实践”。我得到了“TDD with Python”,但它并没有似乎解释了这一点。

  2. 有人可能会告诉我为什么通常会使用unittest2而不是unittest?

  3. 附录

    在Omar Diab努力查看源代码后,我尝试了这个:

    def run( self, *args, **kvargs ):
        result = self.defaultTestResult()
        startTestRun = getattr(result, 'startTestRun', None)
        logger.info( '# calling superclass run... startTestRun? %s' % ( startTestRun, ))
        unittest.TestCase.run( self, *args, **kvargs  )
        logger.info( '# ... superclass run ended')
    

    不幸的是,每个test_XXX方法都给出了:

    # calling superclass run... startTestRun? <bound method TestResult.startTestRun of <unittest.result.TestResult run=0 errors=0 failures=0>>
    
    setUp for test_that_stuff_happened (__main__.xx_FT)
    
    tearDown for test_that_stuff_happened (__main__.xx_FT)
    end tearDown...
    . # ... superclass run ended
    

3 个答案:

答案 0 :(得分:2)

哇,没有回复。我很惊讶。

如果你想在运行开始和运行结束时发生一些事情,大多数人无疑可以自己解决这个问题:

Subclass TestCase,根据:

def setUp( self ):
    if not hasattr( unittest.TestCase, 'app' ):
        unittest.TestCase.app = MyApp()
        def shutdown_func():
            pass # do any end-of-run stuff here
        atexit.register( shutdown_func )
        pass # do any start-of-run stuff here
    self.app = unittest.TestCase.app

然后从这一个中创建所有TestCases子类...

关键是,如果您希望这种情况发生,您的应用程序只构建一次。处理确保每个连续setUp“原始”的责任当然取决于您。 显然,您可以使用setUpClass,但之后您无法访问TestCase实例。

答案 1 :(得分:0)

我遇到了同样的问题,所以我看了一下源代码。

检查unittest.TextTestRunnerunittest.TestCase,看起来startTestRun()stopTestRun()会被手动调用。在unittest.TextTestRunner中,它的工作原理如下:

def run(self, test):
    # ...
    startTestRun = getattr(result, 'startTestRun', None)
    if startTestRun is not None:
        startTestRun()
    # ...

在您的情况下,unittest.TestCase,就像这样:

def run(self, result=None):
    orig_result = result
    if result is None:
        result = self.defaultTestResult()
        startTestRun = getattr(result, 'startTestRun', None)
        if startTestRun is not None:
            startTestRun()
    # ...

如果你没有传递startTestRunTestCase.run()实际上只会被result调用。你传递的是result,所以它没有发生。

这对我来说似乎是个错误!但基本上它意味着您可以扩展TestCaseTestSuite,重新实现run方法,然后手动调用这些方法;或者只是在相应的run方法之外调用它们。

希望这有帮助!

答案 2 :(得分:-1)

认为在TestCase.run()中创建TestResult对象是一种误解,因为无法访问流,描述和详细信息。 以KWarg的形式提供

def run( self, test_result=TestResultX ):
or create TestResult in Runner.run():