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

时间:2018-03-06 08:53:16

标签: python unit-testing tornado

我正试图对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参数的事实?

1 个答案:

答案 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)