Tests fail because of not validated indexing
After updating to latest versions tried to run simple test on a simple application.
# tmp.py
from sanic import Sanic
from sanic.response import json
app = Sanic('app')
@app.get('/')
async def hand1(req):
return json({})
if __name__ == '__main__':
app.run()
# conftest.py
from pytest import fixture
from sanic_testing.manager import TestManager, SanicASGITestClient
from tmp import app
@fixture()
def client() -> SanicASGITestClient:
"""Sanic test app."""
manager = TestManager(app)
yield manager.asgi_client
# test_app.py
import pytest
from sanic_testing.testing import SanicASGITestClient
async def test_sanic_app(client: SanicASGITestClient):
req, res = await client.get("/")
assert res.json == {}
Got the following exception trace:
============================= test session starts ==============================
collecting ... collected 1 item
test_app.py::test_sanic_app FAILED [100%]
tests/test_app.py:4 (test_sanic_app)
client = <sanic_testing.testing.SanicASGITestClient object at 0x7f1f5bfa4610>
async def test_sanic_app(client: SanicASGITestClient):
> req, res = await client.get("/")
test_app.py:6:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
../venv/lib/python3.10/site-packages/httpx/_client.py:1751: in get
return await self.request(
../venv/lib/python3.10/site-packages/sanic_testing/testing.py:364: in request
await self.sanic_app._startup() # type: ignore
../venv/lib/python3.10/site-packages/sanic/app.py:1513: in _startup
self.ext._display()
../venv/lib/python3.10/site-packages/sanic_ext/bootstrap.py:110: in _display
f" > {extension.name} {extension.render_label()}"
../venv/lib/python3.10/site-packages/sanic_ext/extensions/base.py:56: in render_label
label = self.label()
../venv/lib/python3.10/site-packages/sanic_ext/extensions/openapi/extension.py:25: in label
return self._make_url()
../venv/lib/python3.10/site-packages/sanic_ext/extensions/openapi/extension.py:34: in _make_url
else self.app.serve_location
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = Sanic(name="app")
@property
def serve_location(self) -> str:
> server_settings = self.state.server_info[0].settings
E IndexError: list index out of range
../venv/lib/python3.10/site-packages/sanic/mixins/runner.py:574: IndexError
============================== 1 failed in 0.10s ===============================
It seems that this line server_settings = self.state.server_info[0].settings should be inside a validation clause:
@property
def serve_location(self) -> str:
if self.state.server_info:
server_settings = self.state.server_info[0].settings
else:
server_settings = None
return self.get_server_location(server_settings)
In this case test runs successfully.
Python 3.10.5 pytest 7.1.2 pytest-asyncio 0.18.3 sanic 22.6.0 sanic-ext 22.6.1 sanic-routing 22.3.0 sanic-testing 22.6.0
Yes, that makes sense. Probably even better we need to be setting that object in ASGI. I made a similar change in the reusable client in sanic-testing.
Adding app.prepare() appears to correct the issue as well
import pytest
from sanic import Sanic, response
@pytest.fixture
def app():
sanic_app = Sanic("MyApp")
@sanic_app.get("/")
def basic(request):
return response.text("foo")
sanic_app.prepare() # Fixes IndexError: list index out of range
return sanic_app
@pytest.mark.asyncio
async def test_basic_asgi_client(app):
request, response = await app.asgi_client.get("/")
assert request.method.lower() == "get"
assert response.body == b"foo"
assert response.status == 200
Adding
app.prepare()appears to correct the issue as wellimport pytest from sanic import Sanic, response @pytest.fixture def app(): sanic_app = Sanic("MyApp") @sanic_app.get("/") def basic(request): return response.text("foo") sanic_app.prepare() # Fixes IndexError: list index out of range return sanic_app @pytest.mark.asyncio async def test_basic_asgi_client(app): request, response = await app.asgi_client.get("/") assert request.method.lower() == "get" assert response.body == b"foo" assert response.status == 200
O_o what's the sort of magic?!?
O_o what's the sort of magic?!?
https://docs.pytest.org/en/7.1.x/how-to/fixtures.html