单元测试龙卷风应用程序:如何改进错误消息的显示

时间:2017-03-02 09:07:31

标签: python unit-testing tornado

我正在使用unittest测试有多个处理程序的龙卷风应用程序,其中一个引发异常。如果我使用python test.py运行以下测试代码:

# test.py

import unittest
import tornado.web
import tornado.testing

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write('Hello World') # handler works correctly

class HandlerWithError(tornado.web.RequestHandler):
    def get(self):
        raise Exception('Boom') # handler raises an exception
        self.write('Hello World')

def make_app():
    return tornado.web.Application([
        (r'/main/', MainHandler),
        (r'/error/', HandlerWithError),
    ])

class TornadoTestCase(tornado.testing.AsyncHTTPTestCase):

    def get_app(self):
        return make_app()

    def test_main_handler(self):
        response = self.fetch('/main/')
        self.assertEqual(response.code, 200) # test should pass

    def test_handler_with_error(self):
        response = self.fetch('/error/')
        self.assertEqual(response.code, 200) # test should fail with error

if __name__ == '__main__':
    unittest.main()

测试输出如下:

ERROR:tornado.application:Uncaught exception GET /error/ (127.0.0.1)                                                                                                                   
HTTPServerRequest(protocol='http', host='localhost:36590', method='GET', uri='/error/', version='HTTP/1.1', remote_ip='127.0.0.1', headers={'Connection': 'close', 'Host': 'localhost:3
6590', 'Accept-Encoding': 'gzip'})                                                                                                                                                     
Traceback (most recent call last):                                                                                                                                                     
  File "/usr/local/lib/python2.7/dist-packages/tornado/web.py", line 1332, in _execute                                                                                                 
    result = method(*self.path_args, **self.path_kwargs)                                                                                                                               
  File "test.py", line 13, in get                                                                                                                                                      
    raise Exception('Boom') # handler raises an exception                                                                                                                              
Exception: Boom                                                                                                                                                                        
ERROR:tornado.access:500 GET /error/ (127.0.0.1) 19.16ms                                                                                                                               
F.                                                                                                                                                                                     
======================================================================                                                                                                                 
FAIL: test_handler_with_error (__main__.TornadoTestCase)                                                                                                                               
----------------------------------------------------------------------                                                                                                                 
Traceback (most recent call last):                                                                                                                                                     
  File "/usr/local/lib/python2.7/dist-packages/tornado/testing.py", line 118, in __call__                                                                                              
    result = self.orig_method(*args, **kwargs)                                                                                                                                         
  File "test.py", line 33, in test_handler_with_error                                                                                                                                  
    self.assertEqual(response.code, 200) # test should fail with error                                                                                                                 
AssertionError: 500 != 200                                                                                                                                                             

----------------------------------------------------------------------                                                                                                                 
Ran 2 tests in 0.034s                                                                                                                                                                  

FAILED (failures=1)       

但是,我希望unittest报告第二次测试的错误,而不是失败的断言。而且,' Boom'在unittest测试报告之前出现异常,并且不包含对失败的测试函数的引用,这使得很难找到异常的来源。

有关如何处理这种情况的任何建议吗?

提前致谢!

修改

我发现意外的事实是test_handler_with_error实际上是在进行assertEqual断言,而不是抛出错误。例如,以下代码不执行self.assertEqual语句,因此在测试输出中报告ERROR而不是FAIL

# simple_test.py
import unittest

def foo():
    raise Exception('Boom')
    return 'bar'

class SimpleTestCase(unittest.TestCase):
    def test_failing_function(self):
        result = foo()
        self.assertEqual(result, 'bar')

if __name__ == '__main__':
    unittest.main()

2 个答案:

答案 0 :(得分:1)

您可以停用logging,只会显示测试报告:

logging.disable(logging.CRITICAL)

你可以把它放在

  • 创建了TestCase子类
  • test runner

更多信息How can I disable logging while running unit tests in Python Django?

请记住,CI / CD系统实际上使用标准化报告,例如junit然后以更可读/更优雅的方式呈现它 - 更多信息:

答案 1 :(得分:0)

这是预期的行为。您的测试本身断言返回代码是HTTP 200,并且因为这是一个假的正式断言,结果是"失败"而不是"错误"。您可以按照kwaranuk的回答中提到的方式禁止日志,但是您丢失了实际导致HTTP 500错误的信息。

为什么你的代码到达断言而不是抛出?这是因为您的测试代码未调用 HandlerWithError.get。您的测试代码开始使用AsyncHTTPTestCase类提供的HTTP客户端进行异步HTTP GET操作。 (有关详细信息,请检查该类的源代码。)事件循环一直运行,直到HandlerWithError.get通过localhost套接字接收请求,并使用HTTP 500响应该套接字。当HandlerWithError.get失败时,它不会在您的测试函数中引发异常,不仅仅是Google.com上的失败会引发异常:它只会导致HTTP 500。

欢迎来到异步的世界!没有简单的方法可以将断言错误和来自HandlerWithError.get()的回溯整齐地联系起来。