Skip to content

Testing Guide

Terminal window
# All Rust tests
cargo test --workspace
# Single crate
cargo test -p justapi-core
# Python tests
pytest
# With uv
uv run pytest
# Miri (unsafe validation)
cargo +nightly miri test -p justapi-core

Unit tests go at the bottom of the module they test:

#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_normalize_db_url() {
assert_eq!(normalize_db_url("sqlite:///foo.db"), "sqlite:foo.db");
assert_eq!(normalize_db_url("sqlite:////tmp/foo.db"), "sqlite:/tmp/foo.db");
}
}

Use the JustAPITestClient for in-process testing:

from justapi import JustAPIApp, JustAPITestClient
def test_hello_world():
app = JustAPIApp()
@app.get("/hello")
def hello(request):
return {"message": "Hello!"}
client = JustAPITestClient(app)
response = client.get("/hello")
assert response.status == 200
assert response.json() == {"message": "Hello!"}
def test_create_item():
app = JustAPIApp()
@app.post("/items")
def create(request):
data = request.json()
return {"id": 1, **data}
client = JustAPITestClient(app)
response = client.post("/items", body={"name": "Widget", "price": 9.99})
assert response.status == 200
assert response.json()["name"] == "Widget"
def test_404():
app = JustAPIApp()
client = JustAPITestClient(app)
response = client.get("/nonexistent")
assert response.status == 404

For integration tests that need a running server:

tests/test_app.py
from justapi import JustAPIApp
app = JustAPIApp()
@app.get("/health")
def health(request):
return {"status": "ok"}

Then use JustAPITestClient for end-to-end flow tests.

Use proptest for Rust property-based tests:

use proptest::prelude::*;
proptest! {
#[test]
fn test_route_roundtrip(path in ".*") {
// Property: route matching should never panic
let router = Router::new();
// ...
}
}
tests/
├── test_annotations.py
├── test_middleware.py
├── test_responses.py
├── test_multipart.py
├── test_exceptions.py
├── test_db_concurrent.py
└── ...

Every PR runs via .github/workflows/wheels.yml:

  1. cargo test --workspace
  2. cargo clippy -- -D warnings
  3. cargo fmt --check
  4. cargo deny check (advisories, bans, licenses, sources)
  5. cargo miri test -p justapi-core (nightly)
  6. Build wheels for 6 targets (linux x86_64/aarch64, musl, macOS x86_64/aarch64, Windows x64)
  7. pytest after wheel build (Python 3.12 + free-threaded 3.14t)
  8. Publish to PyPI via OIDC trusted publishing (on tagged releases)

On release, .github/workflows/publish.yml handles the standalone publish matrix.