2017-03-02 41 views
0

我使用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)  

不過,我希望單元測試報告錯誤的第二次測試,而不是一個失敗的斷言。此外,「單元」異常的追蹤出現在單元測試測試報告之前,並且不包含對失敗測試函數的引用,這使得很難找到異常的來源。

任何建議如何處理這種情況?

提前致謝!

編輯

我感到意外的是,居然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() 

回答

0

這是正常現象。你的測試本身斷言返回代碼是HTTP 200,並且由於這是一個錯誤的正式斷言,所以結果是「失敗」而不是「錯誤」。您可以按照kwaranuk的回答中提到的方法來抑制日誌,但是您會丟失有關實際導致HTTP 500錯誤的信息。

爲什麼你的代碼到達斷言,而不是拋出?這是因爲您的測試代碼不會調用 HandlerWithError.get。您的測試代碼使用由AsyncHTTPTestCase類提供的HTTP客戶端開始異步HTTP GET操作。 (查看該類的源代碼以獲得詳細信息。)事件循環運行,直到HandlerWithError.get通過本地主機套接字接收請求,並使用HTTP 500對該套接字進行響應。當HandlerWithError.get失敗時,它不會引發在您的測試功能中除外,不僅僅是Google的失敗。com會引發一個例外:它只會導致一個HTTP 500.

歡迎來到異步的世界!沒有簡單的方法將斷言錯誤和HandlerWithError.get()中的追蹤整合起來。

+0

感謝您的回答。我編輯了我的問題,以澄清我的困惑的原因。 –

+0

編輯我的答案:您的測試函數不是直接調用引發異常的函數。 –

1

您可以禁用logging,只有測試報告將顯示:

logging.disable(logging.CRITICAL) 

你可以把例如在

  • 創建TestCase的子類
  • 測試運行

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

請記住,CI/CD系統實際使用標準化的報告如JUnit和那麼目前它更可讀/優雅的方式 - 更多信息: