API coverage with TraceCov#
TraceCov can be used as an optional API
coverage layer for django-modern-rest test suites. It complements regular
integration tests and schemathesis runs by showing which OpenAPI operations
and parameters were actually exercised.
Official docs: https://docs.tracecov.sh/
Note
TraceCov is not bundled with the django-modern-rest.
You have to install it.
uv add --group dev tracecov
poetry add --group dev tracecov
pip install tracecov
Why is this better than regular coverage?#
Most coverage tools measure which lines and branches of your implementation were executed. TraceCov instead measures coverage of your API contract: which OpenAPI operations, parameters, and response variants were exercised.
This matters because “missing contract coverage” often turns into real bugs:
edge cases for parameters, incorrect status codes, or response variants that your
tests never actually reach. With django-modern-rest the OpenAPI schema is
built from the project’s semantic schema (derived from
response validation). That makes TraceCov coverage
tightly aligned with what your implementation claims to support.
Configuration#
How is that wired with django-modern-rest?
tracecov_mapenables tracking for the whole test run.When
tracecov_mapis active, any test that usesdmr_clientordmr_async_clientis automatically included in the TraceCov report.If you also run
schemathesis, theschemathesistest records which validated requests and responses correspond to which OpenAPI operation, so the report can connect execution back to the spec.
To enable tracking, define a session-scoped tracecov_map fixture.
When tracecov_map is configured and TraceCov is installed, dmr_client
and dmr_async_client automatically register requests in tracecov.
1def tracecov_map() -> 'tracecov.CoverageMap | None':
2 """Provide the session ``tracecov`` coverage map for tests."""
3 try:
4 import tracecov # noqa: PLC0415
5 except ImportError: # pragma: no cover
6 return None
7
8 from django_test_app.server.urls import schema # noqa: PLC0415
9
10 return tracecov.CoverageMap.from_dict(schema.convert())
11
To enable TraceCov recording for schemathesis runs, make sure your
schemathesis test explicitly records validated interactions into
tracecov_map via record_schemathesis_interactions(...).
1@schema.parametrize()
2@h_settings(max_examples=_MAX_EXAMPLES)
3@pytest.mark.timeout(0)
4def test_schemathesis(
5 tracecov_map: 'tracecov.CoverageMap | None',
6 *,
7 case: st.Case[Any],
8) -> None:
9 """Ensure that API implementation matches the OpenAPI schema."""
10 if tracecov_map is None: # pragma: no cover
11 pytest.skip(reason='missing `tracecov`')
12
13 from tracecov.schemathesis import helpers # noqa: PLC0415
14
15 # `werkzeug` leaves `REMOTE_ADDR` out of the WSGI environ entirely,
16 # while every real server sets it. Code that looks up the client IP
17 # then behaves differently under test than in production: for example
18 # `django-allauth` rate limiting answers `403` when it cannot find one.
19 response = case.call_and_validate(
20 environ_base={'REMOTE_ADDR': '127.0.0.1'},
21 )
22 # Record interaction for `tracecov` report:
23 tracecov_map.record_schemathesis_interactions(
24 case.method,
25 case.operation.full_path,
26 [helpers.from_response(case.method, response)],
27 )
What will happen here?
schemathesisexecutes requests generated from your OpenAPI schema.After each
schemathesisrequest is validated, the integration callsrecord_schemathesis_interactions(...)to record which OpenAPI operation and parameters were exercised for that verified response.Independently from
schemathesis, any requests performed throughdmr_clientordmr_async_clientare tracked automatically whentracecov_mapis active.TraceCov aggregates coverage across operations, parameters, keywords, and response coverage.
Tip
If TraceCov is not installed, or when tracecov_map is missing or inactive,
fixtures return regular DMR clients without tracking.
When running your tests:
pytest tests/test_integration/test_openapi/test_schema.py
TraceCov generates a report in various formats. See TraceCov docs for details on the generated coverage report.
In short: run schemathesis and regular integration tests together and get
one unified TraceCov view of what your test suite actually exercised.