我在用AsyncHTTPTestCase为使用asyncio事件循环的现有Tornado应用程序编写测试时遇到一些问题。 在这里,我准备了一个简短的模型,在这里我可以重现问题:
应用程序副本
from tornado.platform.asyncio import AsyncIOMainLoop
import asyncio
import tornado.web
class MainHandler(tornado.web.RequestHandler):
async def get(self, *args, **kwargs):
self.write("200 OK")
async def post(self, *args, **kwargs):
self.write("201 OK")
def make_app():
AsyncIOMainLoop().install() # here is how to asyncio loop installed in app I already have
return tornado.web.Application([
(r"/", MainHandler),
], debug=True)
def start_app():
app = make_app()
app.listen(8888)
loop = asyncio.get_event_loop()
loop.set_debug(True)
loop.run_forever()
开始.py
^{pr2}$测试_应用程序副本
import json
from tornado.testing import AsyncHTTPTestCase
import app
class TestHelloApp(AsyncHTTPTestCase):
def get_app(self):
return app.make_app()
def test_get(self):
response = self.fetch('/')
self.assertEqual(response.code, 200)
self.assertEqual(response.body.decode(), '200 OK')
def test_post(self):
response = self.fetch('/', method="POST",
body=json.dumps({"key": "value"}))
self.assertEqual(response.code, 200)
self.assertEqual(response.body.decode(), '201 OK')
使用这种安装方法,asyncio loop应用程序可以正常工作(我的意思是我可以执行请求并获得响应),但是这样的测试失败了,错误如下:
======================================================================
FAIL: test_post (test_app.TestHelloApp)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/biceps/work/torn/.venv/lib/python3.6/site-packages/tornado/testing.py", line 380, in setUp
self._app = self.get_app()
File "/home/biceps/work/torn/test_app.py", line 8, in get_app
return app.make_app()
File "/home/biceps/work/torn/app.py", line 14, in make_app
tornado.platform.asyncio.AsyncIOMainLoop().install()
File "/home/biceps/work/torn/.venv/lib/python3.6/site-packages/tornado/ioloop.py", line 181, in install
assert not IOLoop.initialized()
AssertionError
----------------------------------------------------------------------
Ran 2 tests in 0.006s
FAILED (failures=1)
似乎是由AsyncIOMainLoop()安装的循环。install()命令在测试之间并没有停止,第一个测试通过正常,但第二个测试总是失败。在
当我将AsyncIOMainLoop().install()移到start_app()方法时-测试通过得很好,但我担心在测试期间我使用一个事件循环,但在实际运行的应用程序中我使用asyncio循环。在
因此,针对这些代码测试是通过的:
from tornado.platform.asyncio import AsyncIOMainLoop
import asyncio
import tornado.web
class MainHandler(tornado.web.RequestHandler):
async def get(self, *args, **kwargs):
self.write("200 OK")
async def post(self, *args, **kwargs):
self.write("201 OK")
def make_app():
return tornado.web.Application([
(r"/", MainHandler),
], debug=True)
def start_app():
AsyncIOMainLoop().install()
app = make_app()
app.listen(8888)
loop = asyncio.get_event_loop()
loop.set_debug(True)
loop.run_forever()
Q:我的问题是-如何在该用例中正确地编写测试?当Tornado应用程序使用AsyncIOMainLoop时,如何使用AsyncHTTPTestCase编写测试? 我决定将AsyncIOMainLoop().install()设置为start_app(),而不是make\u app()函数,对吗?在
另外,我已经补充了self.io_循环.clear_instance()到tearDown()-它看起来可能很脏,但在从make\u app()代码调用AsyncIOMainLoop().install()的情况下,它看起来可能很脏。在
def tearDown(self):
self.io_loop.clear_instance()
super().tearDown()
根据文档,我需要在启动应用程序之前安装AsyncIOMainLoop,而不是在制作应用程序时。 documentation
所以现在我确定正确的方法是使用AsyncIOMainLoop安装到start\u app()代码中。在
现在我的模式代码如下:
web1.py
^{pr2}$测试_应用程序副本
此模式也可以工作,在测试期间使用AsyncIOMainLoop。所以我可以使用使用异步循环的库。在我的例子中异步睡眠()例如。在
相关问题 更多 >
编程相关推荐