Sanic Testing
Sanic Testing provides core testing utilities and clients for Sanic applications. This package externalizes the testing functionality previously integrated directly into the main Sanic framework. It is actively maintained, with releases typically aligning with the Sanic release cycle. The current version is 24.6.0.
Common errors
-
SanicException: Sanic app name 'my_app' already in use
cause Attempting to instantiate multiple Sanic applications with the same name, or Sanic registering an app when running tests in a way that causes conflicts.fixWhen creating your Sanic app instances for testing, ensure each has a unique name, e.g., `sanic_app = Sanic(str(uuid.uuid4()))`. The `TestManager` (from `sanic-testing`) generally handles test mode activation, but for older Sanic versions or specific setups, setting `Sanic.test_mode = True` or the environment variable `SANIC_REGISTER=False` might be necessary before app instantiation. -
TypeError: 'URL' object is not callable
cause This error can occur if there's a mismatch or conflict in the `httpx` version required by `sanic-testing` and another dependency, or if the `httpx` client's methods are being called incorrectly.fixEnsure `httpx` is updated to a compatible version with your `sanic-testing` and `sanic` versions. Check the `sanic-testing` changelog and your `sanic` version's requirements for specific `httpx` compatibility. For example, `sanic-testing` v23.6.0 allowed `httpx 0.24`.
Warnings
- breaking The Sanic testing client (originally `sanic.testing`) was moved out of the main Sanic repository into the standalone `sanic-testing` package. Sanic versions prior to 21.3 had it built-in. Users upgrading Sanic to 21.3+ must explicitly install `sanic-testing`.
- breaking Python 3.7 support has been officially dropped. `sanic-testing` versions 23.6.0 and higher require Python 3.8 or newer, aligning with Sanic's own support policy. Python 3.7 reached end-of-life on June 27, 2023.
- gotcha Monkeypatching the `httpx` library directly can inadvertently affect `sanic-testing`'s internal HTTP client calls, leading to unexpected test behavior or infinite recursion. This happens because `sanic-testing` uses `httpx` under the hood.
- gotcha When testing multiple Sanic application instances, especially in parallel test environments, you might encounter `SanicException: Sanic app name 'xxxxxx' already in use`.
- gotcha The ASGI scope for the test client was updated to include `raw_path`. Tests relying on the exact structure or absence of certain keys in the ASGI scope might need adjustments.
Install
-
pip install sanic-testing
Imports
- TestManager
from sanic.testing import SanicTestClient
from sanic_testing import TestManager
- SanicTestClient
from sanic_testing.testing import SanicTestClient
Quickstart
import pytest
from sanic import Sanic, response
from sanic_testing import TestManager
@pytest.fixture
def app():
sanic_app = Sanic("TestSanic")
TestManager(sanic_app) # Attaches test clients to the app instance
@sanic_app.get("/")
async def basic(request):
return response.text("foo")
return sanic_app
def test_basic_sync_client(app):
# Use the sync test client available via app.test_client
request, response = app.test_client.get("/")
assert request.method.lower() == "get"
assert response.body == b"foo"
assert response.status == 200
@pytest.mark.asyncio
async def test_basic_asgi_client(app):
# Use the async ASGI client available via app.asgi_client
request, response = await app.asgi_client.get("/")
assert request.method.lower() == "get"
assert response.body == b"foo"
assert response.status == 200