【问题标题】:Testing Tornado app for 4xx status code测试 Tornado 应用程序的 4xx 状态代码
【发布时间】:2014-09-29 11:16:01
【问题描述】:

考虑以下 Tornado (v 4.0.2) 应用程序,它是官方hello world 示例的一点修改版本:

import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.set_status(400)
        self.write("Hello, world")

application = tornado.web.Application([
    (r"/", MainHandler),
])

if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

如您所见,这里唯一的区别是set_status 调用MainHandler。现在,我将这段代码保存到app.py,然后我打开tests.py,然后我把这个简单的单元测试放在那里:

import tornado.ioloop
from tornado.httpclient import HTTPRequest
from tornado.testing import AsyncHTTPTestCase, gen_test

from app import application

class SimpleTest(AsyncHTTPTestCase):
    def get_app(self):
        return application

    def get_new_ioloop(self):
        return tornado.ioloop.IOLoop.instance()

    @gen_test
    def test_bad_request(self):
        request = HTTPRequest(url=self.get_url('/'))
        response = yield self.http_client.fetch(request)
        self.assertEqual(response.code, 400)

当我使用 python -m tornado.test.runtests tests 运行此测试时,我得到以下结果:

E
======================================================================
ERROR: test_bad_request (tests.SimpleTest)
----------------------------------------------------------------------
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 "/usr/local/lib/python2.7/dist-packages/tornado/testing.py", line 494, in post_coroutine
    timeout=timeout)
  File "/usr/local/lib/python2.7/dist-packages/tornado/ioloop.py", line 418, in run_sync
    return future_cell[0].result()
  File "/usr/local/lib/python2.7/dist-packages/tornado/concurrent.py", line 109, in result
    raise_exc_info(self._exc_info)
  File "/usr/local/lib/python2.7/dist-packages/tornado/gen.py", line 631, in run
    yielded = self.gen.throw(*sys.exc_info())
  File "tests.py", line 18, in test_bad_request
    response = yield self.http_client.fetch(request)
  File "/usr/local/lib/python2.7/dist-packages/tornado/gen.py", line 628, in run
    value = future.result()
  File "/usr/local/lib/python2.7/dist-packages/tornado/concurrent.py", line 111, in result
    raise self._exception
HTTPError: HTTP 400: Bad Request

----------------------------------------------------------------------
Ran 1 test in 0.022s

FAILED (errors=1)
[E 140929 12:55:59 testing:687] FAIL

显然这是正确的,因为处理程序设置了 400 状态码。 但是我怎样才能针对这种情况测试我的应用程序呢?我认为 4xx 代码很有用,所以我不想放弃它们。但是我是 Tornado 的新手,我无法找到测试它们的方法。有吗?

【问题讨论】:

    标签: python unit-testing testing tornado


    【解决方案1】:

    试试这个:

        @gen_test
        def test_bad_request(self):
            request = HTTPRequest(url=self.get_url('/'))
            with self.assertRaises(tornado.httpclient.HTTPError) as context:
                yield self.http_client.fetch(request)
    
            self.assertEqual(context.exception.code, 400)
    

    请参阅assertRaises 的文档。

    【讨论】:

    • 确实有效。但是,应该用context.exception.code 代替context.error.code。还值得一提的是,应该抓住tornado.httpclient.HTTPError,而不是tornado.web.HTTPError。虽然解决方案对我来说看起来不太好(为什么 4xx 响应是一个例外?),但答案是令人满意的。谢谢!
    • 感谢您的更正,我已经更新了我的答案。我认为 Tornado 的 HTTP 客户端如果由于任何原因(包括服务器错误)无法下载 URL,则引发异常是有意义的。无论如何,这就是它提供的 API。 =)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-23
    • 1970-01-01
    • 1970-01-01
    • 2011-11-10
    • 2015-07-25
    • 2016-05-06
    • 2010-12-07
    相关资源
    最近更新 更多