Aiohttp: Teste o erro de loop do cliente com o aplicativo real

Criado em 17 ago. 2018  ·  4Comentários  ·  Fonte: aio-libs/aiohttp

Longa história curta

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

Comportamento esperado

Devo ser capaz de passar meu módulo de aplicativo diretamente para test_client para testar meu aplicativo.

Comportamento real

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".

Passos para reproduzir

# 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'

Seu ambiente

  • SO: Ubuntu 18.04
  • Python: 3.6.5
  • aiohttp: 3.3.2

Gambiarra

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 ?

outdated

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 por async def app.make_app() co-rotina que retorna um novo aplicativo em cada chamada.

Todos 4 comentários

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.

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

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].

Esta página foi útil?
0 / 5 - 0 avaliações