Update to Sanic 22.12 from 21.x broke all app.test_client tests. Examples from the official documentation do not work.
server.py
app = Sanic("app_name")
app.config.RESPONSE_TIMEOUT = 3600
TestManager(app)
# routes defined here
# ...
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000)
test.py
from server import app
def test_deploy_plan():
_, response = app.test_client.get('/some/route')
assert response.status_code == 200
pytest test.py yields:
Sanic app name 'app_name' not found.
App instantiation must occur outside if __name__ == '__main__' block or by using an AppLoader.
See https://sanic.dev/en/guide/deployment/app-loader.html for more details.
Traceback (most recent call last):
File "<redacted>/venv/lib/python3.9/site-packages/sanic/app.py", line 1491, in get_app
return cls._app_registry[name]
KeyError: 'app_name'
During handling of the above exception, another exception occurred:
[...]
App instantiation must occur outside if __name__ == '__main__' block or by using an AppLoader.
See https://sanic.dev/en/guide/deployment/app-loader.html for more details.
[2023-02-08 17:38:18 -0800] [6280] [ERROR] Not all workers acknowledged a successful startup. Shutting down.
One of your worker processes terminated before startup was completed. Please solve any errors experienced during startup. If you do not see an exception traceback in your error logs, try running Sanic in in a single process using --single-process or single_process=True. Once you are confident that the server is able to start without errors you can switch back to multiprocess mode.
------------------------------ Captured log call ------------------------------
INFO sanic.root:motd.py:54 Sanic v22.12.0
INFO sanic.root:motd.py:54 Goin' Fast @ http://127.0.0.1:57940
INFO sanic.root:motd.py:54 mode: production, ASGI
INFO sanic.root:motd.py:54 server: sanic, HTTP/1.1
INFO sanic.root:motd.py:54 python: 3.9.16
INFO sanic.root:motd.py:54 platform: macOS-12.4-arm64-arm-64bit
INFO sanic.root:motd.py:54 packages: sanic-routing==22.8.0, sanic-testing==22.6.0
ERROR sanic.error:manager.py:230 Not all workers acknowledged a successful startup. Shutting down.
One of your worker processes terminated before startup was completed. Please solve any errors experienced during startup. If you do not see an exception traceback in your error logs, try running Sanic in in a single process using --single-process or single_process=True. Once you are confident that the server is able to start without errors you can switch back to multiprocess mode.
This used to work in Sanic 21.x:
from server import app
def test_route_returns_200():
request, response = app.test_client.get('/some/route')
assert response.status == 200
Another official example defines the routes in the app inside the fixture, which doesn't help me because all the app functionality is defined in a different module:
# official doc example, not good for this purpose
import pytest
@pytest.fixture
def app():
sanic_app = Sanic(__name__)
TestManager(sanic_app)
@sanic_app.get("/")
def basic(request):
return response.text("foo")
return sanic_app
def test_basic_test_client(app):
request, response = app.test_client.get("/")
assert response.body == b"foo"
assert response.status == 200
I found a way to do this.