Python Integration
This guide shows how to integrate TraceCov into your Python test suite. We'll cover tracking API calls against your OpenAPI schema, recording individual requests, generating coverage reports, and analyzing traffic from third-party formats like Postman Collections and HAR files.
Installation
TraceCov is available as a Python package:
$ uv pip install tracecov
Basic Usage
The core workflow with TraceCov involves three steps: creating a coverage map, tracking API calls, and generating a report.
Step 1: Create a CoverageMap Instance
First, create a coverage map by providing your OpenAPI schema:
import tracecov
coverage = tracecov.CoverageMap.from_dict({
"openapi": "3.0.0",
"info": {"title": "Example API", "version": "1.0.0"},
"paths": {
# Your API paths here
}
})
# Alternatively, load from a file path
# coverage = tracecov.CoverageMap.from_path("openapi.json")
Step 2: Track API calls
TraceCov offers multiple ways to track API calls, depending on your testing approach and existing code structure:
import requests
# Option A: Create and configure a session
session = coverage.requests.track_session(requests.Session())
session.headers.update({"Authorization": "Bearer token"})
# Use the session as normal - all requests will be tracked
response = session.get("https://api.example.com/users/1")
response = session.post("https://api.example.com/users", json={"name": "Alice"})
# Option B: Record individual requests manually
response = requests.get("https://api.example.com/users/1")
coverage.requests.record(request=response.request, response=response)
# Option C: Pass a response hook to each call
hook = coverage.requests.response_hook()
response = requests.get(
"https://api.example.com/users/1", hooks={"response": [hook]}
)
Step 3: Generate a Coverage Report
Once you've tracked your API interactions, generate an HTML report to visualize your coverage:
# Store an HTML report to a file
# Default filename is coverage.html
coverage.save_report(output_file="my-api-coverage.html")
# Or get it as a string
html = coverage.generate_report()
Using with other HTTP clients
TraceCov also supports httpx:
import httpx
client = coverage.httpx.track_client(httpx.Client())
# Use the client as normal - all requests will be tracked
# Async client works too!
client = coverage.httpx.track_client(httpx.AsyncClient())
FastAPI / Starlette
FastAPI's TestClient inherits from httpx.Client, so it works with the httpx integration:
from fastapi import FastAPI
from fastapi.testclient import TestClient
app = FastAPI()
coverage = tracecov.CoverageMap.from_dict(app.openapi())
client = coverage.httpx.track_client(TestClient(app))
response = client.get("/users/1")
Django / Django REST Framework
TraceCov integrates with Django's test Client and Django REST Framework's APIClient:
from django.test import Client
import tracecov
coverage = tracecov.CoverageMap.from_path("openapi.json")
# Wrap the test client
client = coverage.django.track_client(Client())
# All requests are automatically tracked
response = client.get("/api/users/")
response = client.post("/api/users/", {"name": "John"}, content_type="application/json")
For Django REST Framework's APIClient:
from rest_framework.test import APIClient
client = coverage.django.track_client(APIClient())
client.credentials(HTTP_AUTHORIZATION=f"Token {token}")
response = client.get("/api/protected/")
Manual recording is also supported:
client = Client()
response = client.get("/api/users/")
# Elapsed time is measured automatically with track_client,
# but can be passed manually when using record directly
coverage.django.record(response.wsgi_request, response, elapsed=0.5)
You can also use RequestFactory or APIRequestFactory to build requests directly without making HTTP calls:
from django.test import RequestFactory
from rest_framework.test import APIRequestFactory
# Django's RequestFactory
factory = RequestFactory()
request = factory.post("/api/users/", {"name": "John"}, content_type="application/json")
# DRF's APIRequestFactory (supports format parameter)
factory = APIRequestFactory()
request = factory.post("/api/users/", {"name": "John"}, format="json")
# Call your view directly
response = my_view(request)
# Record for coverage
coverage.django.record(request, response)
Flask
TraceCov integrates with Flask's test client:
from flask import Flask
import tracecov
app = Flask("myapp")
@app.route("/api/users/", methods=["GET", "POST"])
def users():
return {"status": "ok"}
coverage = tracecov.CoverageMap.from_path("openapi.json")
# Wrap the test client
client = coverage.flask.track_client(app.test_client())
# All requests are automatically tracked
response = client.get("/api/users/")
response = client.post("/api/users/", json={"name": "John"})
Manual recording is also supported:
from flask import Flask
import tracecov
app = Flask("myapp")
@app.route("/api/users/")
def users():
return {"status": "ok"}
coverage = tracecov.CoverageMap.from_path("openapi.json")
client = app.test_client()
response = client.get("/api/users/")
# Access the request from the response
coverage.flask.record(response.request, response, elapsed=0.5)
Using with pytest
Using the following snippet you can automatically track coverage across multiple tests:
import pytest
import requests
import tracecov
@pytest.fixture(scope="session")
def coverage():
# Load your OpenAPI schema
coverage = tracecov.CoverageMap.from_path("openapi.json")
yield coverage
coverage.save_report()
@pytest.fixture(scope="session")
def api_client(coverage):
return coverage.requests.track_session(requests.Session())
def test_get_user(api_client):
response = api_client.get("https://api.example.com/users/1")
assert response.status_code == 200
Using with Schemathesis
Schemathesis is a property-based testing tool for APIs. TraceCov can track all API calls made during Schemathesis test runs:
Step 1: Create a Python file (e.g. hooks.py)
import tracecov
tracecov.schemathesis.install()
Step 2: Set the SCHEMATHESIS_HOOKS environment variable
$ export SCHEMATHESIS_HOOKS=hooks
Step 3: Run Schemathesis
$ schemathesis run https://example.schemathesis.io/openapi.json \
--coverage-format=html
...
Schema Coverage report: ./schema-coverage.html
Note
TraceCov supports Schemathesis 4.0 and above.
Low-Level API
For advanced use cases or integration with custom HTTP clients, TraceCov provides a low-level API that accepts generic request and response objects:
from tracecov import HttpRequest, HttpResponse
coverage.record(
request=HttpRequest(
method="GET",
url="https://api.example.com/users/1",
body=None,
headers={},
),
response=HttpResponse(status_code=200, elapsed=1.3),
)
Third-Party Format Integrations
Professional Edition
HAR, Postman, and VCR import features require TraceCov Professional.
TraceCov has built-in support for common API traffic formats.
Postman Collections
If you use Postman for API testing, TraceCov can analyze your collections to measure coverage:
import json
# Load and analyze a Postman Collection from a file
coverage.postman.record_from_path("path/to/collection.json")
# Analyze a collection from a dictionary
with open("path/to/collection.json") as fd:
collection = json.load(fd)
coverage.postman.record_from_dict(collection)
Note
TraceCov supports Postman Collection formats v1.0, v2.0, and v2.1.
HTTP Archive (HAR) Files
TraceCov can analyze HAR files exported from browser dev tools or API tools:
import json
# Load and analyze a HAR file
coverage.har.record_from_path("path/to/traffic.har")
# Analyze HAR data from a dictionary
with open("path/to/traffic.har") as fd:
har = json.load(fd)
coverage.har.record_from_dict(har)
Note
TraceCov supports HAR formats v1.2 and v1.3 from Chrome, Firefox, Edge, Postman, and other tools that export standard HAR format.
VCR Cassettes
TraceCov can analyze VCR cassette files:
import json
# Load and analyze a VCR cassette from a file
coverage.vcr.record_from_path("path/to/cassette.json")
# Analyze a cassette from a dictionary
with open("path/to/cassette.json") as fd:
cassette = json.load(fd)
coverage.vcr.record_from_dict(cassette)
Note
Cassettes from Ruby's VCR library and Schemathesis are supported.