O padrão de teste sugerido requer duplicação padrão do código do aplicativo e não mostra o teste do aplicativo diretamente.
https://docs.aiohttp.org/en/stable/testing.html#pytest
Devo ser capaz de passar meu módulo de aplicativo diretamente para test_client
para testar meu aplicativo.
Os documentos mostram a construção do aplicativo a partir de manipuladores dinâmicos antes de cada teste. Passar o app
real diretamente para test_client
funciona bem na primeira vez, depois falha com "RuntimeError: instância web.Application inicializada com loop diferente".
# 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'
Por enquanto, resolvi o problema dando uma olhada no código-fonte e determinando a causa do erro.
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
Não está imediatamente claro para mim por que esse código é necessário. Não consegui encontrar nenhum contexto na história do git. Definir app._loop = None
no meu método de limpeza de teste parece evitar o problema sem quaisquer efeitos colaterais negativos. Este código é realmente necessário? Essa correção poderia ser integrada em test_client
?
Application
é um objeto com estado, ele deve ser recriado para cada teste da suíte de teste de unidade.
O tempo de vida do aplicativo deve ser menor do que o do loop de evento.
Dica: substitua app.app
por async def app.make_app()
co-rotina que retorna um novo aplicativo em cada chamada.
Adicionar def make_app()
a app.py
? Isso faz sentido.
O tornado FWIW promove o padrão make_app()
em seu primeiro exemplo. Não acho que zombar do aplicativo no arquivo de teste seja um bom padrão para os documentos promoverem.
Honestamente, não acho que zombar de qualquer objeto aiohttp
seja um bom padrão
Este tópico foi bloqueado automaticamente, pois não houve nenhuma atividade recente depois que ele foi fechado. Abra um [novo problema] para bugs relacionados.
Se você acha que há pontos importantes nesta discussão, inclua esses pontos nessa [nova edição].
Comentários muito úteis
Application
é um objeto com estado, ele deve ser recriado para cada teste da suíte de teste de unidade.O tempo de vida do aplicativo deve ser menor do que o do loop de evento.
Dica: substitua
app.app
porasync def app.make_app()
co-rotina que retorna um novo aplicativo em cada chamada.