Pytest Plugin¶
The nature of applications built with the starlite-saqlalchemy pattern is that they rely heavily
on connected services.
Abstraction of PostgreSQL and Redis connectivity boilerplate is a nice convenience, however to successfully patch the application for testing requires deeper knowledge of the implementation than would be otherwise necessary.
So, starlite-saqlalchemy ships with a selection of pytest fixtures that are often necessary
when building applications such as these.
app¶
The app fixture provides an instance of a Starlite application.
from __future__ import annotations
from starlite import Starlite
def test_app_fixture(app: Starlite) -> None:
assert isinstance(app, Starlite)
The value of Pytest ini option, test_app is used to determine the application to load.
If no value is configured for the test_app ini option, the default location of
"app.main:create_app" is searched.
The value of the test_app ini option can either point to an application factory or Starlite
instance.
If the object found at the import path is not a Starlite instance, the fixture assumes it is
an application factory, and will call the object and return the response.
The value of test_app is resolved using the uvicorn import_from_string() function, so it
supports the same format as uvicorn supports for its app and factory parameters.
client¶
A starlite.testing.TestClient instance, wired to the same application that is produced by the
app fixture.
cap_logger¶
The cap_logger fixture provides an instance of structlog.testing.CapturingLogger.
from __future__ import annotations
from typing import TYPE_CHECKING
from structlog.testing import CapturedCall
if TYPE_CHECKING:
from structlog.testing import CapturingLogger
def test_app_fixture(cap_logger: CapturingLogger) -> None:
cap_logger.info("hello")
cap_logger.info("hello", when="again")
assert cap_logger.calls == [
CapturedCall(method_name="info", args=("hello",), kwargs={}),
CapturedCall(method_name="info", args=("hello",), kwargs={"when": "again"}),
]
The cap_logger fixture will capture any structlog calls made by the starlite application or the
SAQ worker, so that they can be inspected as part of tests.
from __future__ import annotations
from typing import TYPE_CHECKING
from httpx import AsyncClient
if TYPE_CHECKING:
from starlite import Starlite
from structlog.testing import CapturingLogger
async def test_health_logging_skipped(
app: Starlite, cap_logger: CapturingLogger
) -> None:
"""Test that calls to the health check route are not logged."""
async with AsyncClient(app=app, base_url="http://testserver") as client:
response = await client.get("/health")
assert response.status_code == 200
assert [] == cap_logger.calls
is_unit_test¶
The is_unit_test fixture returns a bool that indicates if the test suite believes it is running
a unit test, or an integration test.
To determine this, we compare the path of the running test to the value of the Pytest ini option
unit_test_pattern, which by default is "^.*/tests/unit/.*$".
This fixture is used to make fixtures behave differently between unit and integration test contexts.
_patch_http_close¶
This is an autouse fixture, that prevents HTTP clients that are defined in the global scope
from being closed.
The application is configured to close all instantiated HTTP clients on app shutdown, however when apps are defined in a global/class scope, a test that runs after the first application shutdown in the test suite would fail.
_patch_sqlalchemy_plugin¶
This is an autouse fixture, that mocks out the on_shutdown method of the SQLAlchemy config
object for unit tests.
_patch_worker¶
This is an autouse fixture, that mocks out the on_app_startup and stop methods of
worker.Worker type for unit tests.