在哪里适合安装Tornado应用程序的AsyncIOMainLoop()

时间:2018-02-09 07:37:21

标签: python unit-testing tornado

所以我怀疑安装AsyncIOMainLoop()的两种方法是什么我认为更真实。哪一个更合适?

第一当make_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():
    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

使用第二个,当在start_app()代码中安装了AsyncIOMainLoop()时 - 测试运行正常,但在这里我怀疑在测试期间没有使用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()的真正方法是什么?

1 个答案:

答案 0 :(得分:0)

绝对是documentation所说的第二个例子:

from tornado.platform.asyncio import AsyncIOMainLoop
import asyncio
AsyncIOMainLoop().install()
asyncio.get_event_loop().run_forever()

关键是在告诉AsyncIOMainLoop运行循环之前必须先安装asyncio