Fluent, chainable assertions for everything you test in Python. One vocabulary — from a single value to HTTP responses, JSON, HTML, MCP, and architecture. Inspired by Laravel's elegant testing API.
Full documentation lives at othercodes.github.io/pyssertive.
- Installation
- Quickstart
- Guides: Expectations · HTTP · JSON · HTML · Database · Architecture · MCP
- API Reference
- One fluent vocabulary for any value, response, or contract under test
- HTTP status code assertions (2xx, 3xx, 4xx, 5xx)
- JSON response validation with path navigation, fragments, and JSON Schema contract testing
- HTML content assertions with CSS-selector scoping
- Template, context, session, cookie, and header assertions
- Streaming response and file download assertions
- Architecture assertions for import boundaries, layers, and bounded-context isolation
- MCP (Model Context Protocol) assertions with MCP-native vocabulary
- Debug helpers for test development
- Python 3.10+
- Django 4.2, 5.2, or 6.0 (optional, only if using the Django adapter)
- httpx 0.27+ (optional, only if using the httpx adapter for FastAPI/Starlette/FastMCP)
pip install pyssertive # core
pip install pyssertive[django] # with Django adapter
pip install pyssertive[httpx] # with httpx adapter (FastAPI, Starlette, FastMCP)from pyssertive import expect
# Generic values — one vocabulary for anything
expect(42).equals(42)
expect([1, 2, 3]).has_count(3).contains(2).does_not_contain(99)
expect("alice@example.com").is_instance_of(str).matches(r".+@.+")
# The same expect dispatches to specialized assertables
expect.json(payload).where("status", "active").missing("password")
expect.html(markup).see_text("Welcome back, Alice")
expect.arch("myapp.domain").should_only_depend_on(["stdlib", "myapp.domain"])HTTP responses chain fluently from a test client:
import pytest
from pyssertive.adapters.django import FluentHttpAssertClient
@pytest.fixture
def client():
from django.test import Client
return FluentHttpAssertClient(Client())
@pytest.mark.django_db
def test_user_api(client):
client.get("/api/users/")\
.assert_ok()\
.assert_json_path("count", 10)\
.assert_header("Content-Type", "application/json")See the documentation for the full guides and API reference.
MIT — see LICENSE.