【发布时间】:2018-02-09 07:37:21
【问题描述】:
所以我怀疑我看到的两种安装 AsyncIOMainLoop() 的方法中哪一种更正确。哪个更合适?
1st 当 AsyncIOMainLoop() 安装在 make_app() 代码中时:
class MainHandler(tornado.web.RequestHandler):
async def get(self, *args, **kwargs):
return self.write("OK")
async def post(self, *args, **kwargs):
return self.write("OK")
def make_app():
tornado.platform.asyncio.AsyncIOMainLoop().install()
return tornado.web.Application([(r"/", MainHandler),],
debug=False)
def start_app():
app = make_app()
app.listen(8888)
asyncio.get_event_loop().run_forever()
if __name__ == "__main__":
start_app()
第二次在 start_app() 代码中安装 AsyncIOMainLoop() 时:
class MainHandler(tornado.web.RequestHandler):
async def get(self, *args, **kwargs):
return self.write("OK")
async def post(self, *args, **kwargs):
return self.write("OK")
def make_app():
return tornado.web.Application([(r"/", MainHandler),],
debug=False)
def start_app():
tornado.platform.asyncio.AsyncIOMainLoop().install()
app = make_app()
app.listen(8888)
asyncio.get_event_loop().run_forever()
if __name__ == "__main__":
start_app()
您认为这两种方法中哪一种更合适?
对于第一个,我在一个 AsyncHTTPTestCase 套件中运行超过 2 个测试时遇到了问题,错误如下:
Traceback (most recent call last):
File "/home/kamyanskiy/.local/share/virtualenvs/test-0zFWLpVX/lib/python3.6/site-packages/tornado/testing.py", line 380, in setUp
self._app = self.get_app()
File "/home/kamyanskiy/work/test/test_app.py", line 10, in get_app
return web1.make_app()
File "/home/kamyanskiy/work/test/web1.py", line 74, in make_app
tornado.platform.asyncio.AsyncIOMainLoop().install()
File "/home/kamyanskiy/.local/share/virtualenvs/test-0zFWLpVX/lib/python3.6/site-packages/tornado/ioloop.py", line 181, in install
assert not IOLoop.initialized()
AssertionError
对于第二个,当 AsyncIOMainLoop() 安装在 start_app() 代码中时 - 测试运行正常,但在这里我怀疑在测试期间 AsyncIOMainLoop() 没有使用。
测试看起来像:
from tornado.testing import AsyncHTTPTestCase
import web1
class TestTornadoAppBase(AsyncHTTPTestCase):
def get_app(self):
return web1.make_app()
# I have to uncomment this for 1st code example
# def tearDown(self):
# self.io_loop.clear_instance()
# super().tearDown()
class TestGET(TestTornadoAppBase):
def test_root_get_method(self):
response = self.fetch("/")
self.assertEqual(response.code, 200)
self.assertEqual(response.body.decode(), 'OK')
def test_root_post_method(self):
response = self.fetch("/", method="POST", body='{"k": "v"}')
self.assertEqual(response.code, 200)
self.assertEqual(response.body.decode(), 'OK')
那么选择在哪里初始化 AsyncIOMainLoop() 的真正方法是什么?
【问题讨论】:
-
在您的示例中,我看不到您需要安装
AsyncIOMainLoop的任何要求。 -
@Sraw 你是对的,但这是一个简单的例子,就像我必须用测试覆盖的项目的“伪”代码一样,并且 AsyncIOMainLoop 用于使用需要 asyncio 循环的 aio 库,所以Tornado 应用程序必须使用 AsyncIOMainLoop 运行。使用 tornado 的原生 ioloop 似乎减轻了 100% 的痛苦。
-
所以在这种情况下,我认为你需要覆盖
get_new_ioloop。参考:tornadoweb.org/en/stable/… -
@Sraw 谢谢你,好建议。所以使用 get_new_ioloop() 我总是在测试中使用 AsyncIOMainLoop,很好。
标签: python unit-testing tornado