Aiohttp: 使用实际应用程序测试客户端循环错误

创建于 2018-08-17  ·  4评论  ·  资料来源: aio-libs/aiohttp

长话短说

建议的测试模式需要应用程序代码的样板重复,并且不显示直接测试应用程序。

https://docs.aiohttp.org/en/stable/testing.html#pytest

预期行为

我应该能够将我的应用程序模块直接传递给test_client来测试我的应用程序。

实际行为

文档显示了在每次测试之前从处理程序动态构建应用程序。 第一次将真实的app直接传递给test_client工作正常,然后失败并显示“RuntimeError: web.Application instance initialized with different loop”。

重现步骤

# handler.py

async def foo():
    return 'foo'
# app.py

from aiohttp import web
from .handler import foo

app = web.Application()
app.add_routes([web.get('/foo/', foo)])
# test.py

from .app import app

async def test_foo_status(test_client):
    response = await client.get('/foo/')
    assert response.status == 200

async def test_foo_body(test_client):
    response = await client.get('/foo/')
    body = await response.text()
    assert body == 'foo'

您的环境

  • 操作系统:Ubuntu 18.04
  • 蟒蛇:3.6.5
  • aiohttp: 3.3.2

解决

我暂时通过查看源代码并确定错误原因来解决这个问题。

        if self._loop is not None and self._loop is not loop:
            raise RuntimeError(
                "web.Application instance initialized with different loop")

https://github.com/aio-libs/aiohttp/blob/e561eaa/aiohttp/web_app.py#L134

我不清楚为什么需要这段代码。 我在 git 历史中找不到任何上下文。 在我的测试清理方法中设置app._loop = None似乎可以避免该问题而没有任何负面影响。 这段代码真的有必要吗? 此修复程序是否可以集成到test_client

outdated

最有用的评论

Application是一个有状态的对象,它应该为单元测试套件中的每个测试重新创建。
应用程序的生命周期应该比事件循环的生命周期短。

提示:将app.app替换async def app.make_app()协程,每次调用都会返回一个新的应用程序。

所有4条评论

Application是一个有状态的对象,它应该为单元测试套件中的每个测试重新创建。
应用程序的生命周期应该比事件循环的生命周期短。

提示:将app.app替换async def app.make_app()协程,每次调用都会返回一个新的应用程序。

def make_app()app.py ? 那讲得通。

FWIW 龙卷风在他们的第一个例子中推广了make_app()模式。 我不认为在测试文件中模拟应用程序是文档推广的好模式。

http://www.tornadoweb.org/en/stable/#hello -world

老实说,我不认为嘲笑任何aiohttp对象是一个好模式

由于关闭后没有任何近期活动,因此该线程已自动锁定。 请打开 [新问题] 以获取相关错误。
如果您觉得本次讨论中有重要观点,请将这些摘录包含在该 [新问题] 中。

此页面是否有帮助?
0 / 5 - 0 等级