我正试图对Tornado应用程序进行单元测试。
我的测试(test_POST_empty_json_in_do_nothing
)的目标现在只是发送空压缩json的POST请求。当它收到请求时,HTTPServer必须只返回一个HTTP代码200。
关注this example我重写get_http_server
以使用make_server
函数返回我的HTTPServer。据我所知,通过这种方式,测试模块将在测试期间自动使用此服务器。
test_main_server.py
class TestMainServer(AsyncHTTPSTestCase):
def get_app(self):
return ecomtranslatorSrv.make_app()
def get_http_server(self):
return ecomtranslatorSrv.make_server(self._app, self.io_loop)
def test_GET_main_handler(self):
response = self.fetch('/')
self.assertEqual(response.code, 200)
def test_POST_empty_json_in_do_nothing(self):
headers = tornado.httputil.HTTPHeaders({"Content-Type": "application/json", 'Content-Encoding': 'gzip'})
response = self.fetch(method='POST', path='/basket/json_in', headers=headers, body='{}')
self.assertEqual(response.code, 200)
def main():
tornado.testing.main()
if __name__ == '__main__':
main()
main_server.py
class MainHandler(tornado.web.RequestHandler):
def get(self):
pass
class NewBasketHandler(tornado.web.RequestHandler):
def post(self):
pass
def make_app():
return tornado.web.Application([
(MAIN_HANDLER, MainHandler),
(NEW_BASKET, NewBasketHandler)
])
def make_server(app, io_loop=None):
return tornado.httpserver.HTTPServer(app, io_loop=io_loop, decompress_request=True)
但这样做两个测试都失败了:
AssertionError:异步操作在5秒后超时
所以我的第一个问题是:为什么会这样?
当然如果我完全删除get_http_server
函数,两个测试都会通过,但Tornado也会返回:
警告:tornado.general:不支持的内容编码:gzip
这是有道理的,因为我使用的HTTPServer没有decompress_request
参数。
我不明白如何在测试模块中使用make_server
函数返回的HTTPServer,即使用我想要的参数创建的服务器。
以另一种方式:我如何测试我的服务器需要decompress_request参数的事实?
答案 0 :(得分:0)
由于龙卷风的帮助,我设法解决了issue。 我在这里报告他们告诉我的事情:
你不应该覆盖get_http_server() - 如果你想要的话 decompress_request选项,你应该将其返回 get_httpserver_options()
覆盖get_httpserver_options()是记录的方法 定制这个。正如您所见,您必须依赖私有_app 要覆盖get_http_server的属性。
但为什么要超时呢?您是AsyncHTTPSTestCase的子类 - 请注意 S.这意味着你需要创建一个支持TLS的服务器 必须将ssl_options传递给HTTPServer构造函数。没有那个 您正在创建一个未加密的服务器,该服务器不知道如何操作 解释TLS握手(并且它不包含魔法\ r \ n \ r \ n 字节序列,所以服务器只是坐在那里等待HTTP 要求完成)。
所以我创建了一个新证书:
openssl req -x509 -newkey rsa:4096 -sha256 -nodes -keyout test.key -out test.crt -subj "/CN=example.com" -days 3650
并使用此命令创建的文件来创建ssl证书。我把它传递给HTTPServer。
def make_server(app):
ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
ssl_ctx.load_cert_chain(os.path.join(CERTIFICATE_PATH, test.crt), os.path.join(KEY_PATH, test.key))
return tornado.httpserver.HTTPServer(app, decompress_request=True, ssl_options=ssl_ctx)