El patrón de prueba sugerido requiere la duplicación estándar del código de la aplicación y no muestra cómo probar la aplicación directamente.
https://docs.aiohttp.org/en/stable/testing.html#pytest
Debería poder pasar el módulo de mi aplicación directamente a test_client
para probar mi aplicación.
Los documentos muestran cómo compilar la aplicación a partir de controladores sobre la marcha antes de cada prueba. Pasar el app
real directamente a test_client
funciona bien la primera vez, luego falla con "RuntimeError: instancia web.Application inicializada con bucle 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 ahora, esquivé el problema mirando el código fuente y determinando la causa del error.
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
No me queda claro de inmediato por qué es necesario este código. No pude encontrar ningún contexto en la historia de git. Establecer app._loop = None
en mi método de limpieza de prueba parece evitar el problema sin efectos secundarios negativos. ¿Es este código realmente necesario? ¿Podría esta solución integrarse en test_client
?
Application
es un objeto con estado, debe recrearse para cada prueba desde el conjunto de pruebas unitarias.
La vida útil de la aplicación debe ser más corta que la del bucle de eventos.
Sugerencia: reemplace app.app
con async def app.make_app()
coroutine que devuelve una nueva aplicación en cada llamada.
Agregar def make_app()
a app.py
? Eso tiene sentido.
FWIW tornado promueve el patrón make_app()
en su primer ejemplo. No creo que burlarse de la aplicación en el archivo de prueba sea un buen patrón para que los documentos promocionen.
Honestamente, no creo que burlarse de cualquier objeto aiohttp
sea un buen patrón
Este hilo se ha bloqueado automáticamente ya que no ha habido ninguna actividad reciente después de que se cerró. Abra un [número nuevo] para errores relacionados.
Si cree que se han hecho puntos importantes en esta discusión, incluya esas excepciones en ese [nuevo número].
Comentario más útil
Application
es un objeto con estado, debe recrearse para cada prueba desde el conjunto de pruebas unitarias.La vida útil de la aplicación debe ser más corta que la del bucle de eventos.
Sugerencia: reemplace
app.app
conasync def app.make_app()
coroutine que devuelve una nueva aplicación en cada llamada.