使用 Tornado 框架对 HTTPServer 创建进行单元测试



我正在尝试对龙卷风应用程序进行单元测试。

我的测试(test_POST_empty_json_in_do_nothing)的目标现在只是发送空压缩json的POST请求。当它收到请求时,HTTPServer 必须只返回 HTTP 代码 200。

在这个例子之后,我覆盖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)

但是这样做两个测试都失败了:

断言错误:异步操作在 5 秒后超时

所以我的第一个问题是:为什么会这样?

当然,如果我完全删除get_http_server功能,两个测试都会通过,但龙卷风也会返回:

警告:龙卷风.常规:不支持的内容编码:gzip

这是有道理的,因为我使用的是没有decompress_request参数的HTTPServer。

我不明白如何在测试模块中使用make_server函数返回的 HTTPServer,即使用我想要的参数创建的服务器。

换句话说:如何测试我的服务器需要decompress_request参数的事实?

多亏了龙卷风的家伙的帮助,我设法解决了这个问题。 我在这里报告他们告诉我的内容:

你不应该覆盖get_http_server() - 如果你想要 decompress_request选项,您应该将其退回 get_httpserver_options()

重写 get_httpserver_options() 是记录在案的方法 自定义此内容。如您所见,您必须依靠私人_app 属性以覆盖get_http_server。

但是为什么会超时呢?您正在子类化异步HTTPSTestCase - 注意 S.这意味着您需要创建一个启用 TLS 的服务器,因此您 必须ssl_options传递给 HTTPServer 构造函数。没有那个 您正在创建一个未加密的服务器,该服务器不知道如何 解释 TLS 握手(它不包含魔术 \r\r 字节序列,所以服务器只是坐在那里等待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)

最新更新