swadhinbiswas πŸ“š docs: update README and docs_site with CI/CD, uv, security, OIDC changes Β· 7/25/2026
65afe21
160 lines Β· 3.4 KB
Raw Download

title: Testing Guide
description: How to write and run tests for JustAPI β€” a high-performance FastAPI alternative built in Rust.
keywords: testing guide, pytest, FastAPI alternative, Rust web framework, test automation

Running Tests

# 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

Writing Rust Tests

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");
    }
}

Writing Python Tests

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!"}

Testing POST Endpoints

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"

Testing Errors

def test_404():
    app = JustAPIApp()
    client = JustAPITestClient(app)
    response = client.get("/nonexistent")
    assert response.status == 404

Integration Testing

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.

Property-Based Testing

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();
        // ...
    }
}

Test File Layout

tests/
β”œβ”€β”€ test_annotations.py
β”œβ”€β”€ test_middleware.py
β”œβ”€β”€ test_responses.py
β”œβ”€β”€ test_multipart.py
β”œβ”€β”€ test_exceptions.py
β”œβ”€β”€ test_db_concurrent.py
└── ...

CI Testing

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.

See Also