Fluent assertion library for Python with composable matchers, structural matching, and full type safety
Project description
Fluent assertion library for Python with composable matchers, structural matching, and full type safety.
A modern, batteries-included fork of assertpy.
Quick start
pip install assertpy2 # drop-in replacement for assertpy, just change the import
from assertpy2 import assert_that
def test_user():
user = {"name": "Alice", "age": 30, "roles": ["viewer", "editor"]}
assert_that(user).contains_key("name", "age")
assert_that(user["age"]).is_between(18, 120)
assert_that(user["roles"]).contains("viewer").does_not_contain("admin")
assert_that(user).has_name("Alice")
Why fluent assertions?
# bare assert - passes, but failure message is useless
assert user["age"] >= 18
# AssertionError
# assertpy2 - same check, clear failure message
assert_that(user["age"]).is_greater_than_or_equal_to(18)
# AssertionError: Expected <16> to be greater than or equal to <18>, but was not.
# bare assert - three separate statements
assert isinstance(items, list)
assert len(items) == 3
assert "admin" in items
# assertpy2 - one fluent chain
assert_that(items).is_type_of(list).is_length(3).contains("admin")
Type-aware autocomplete
assert_that() uses @overload to return type-specific Protocols.
Your IDE shows only methods relevant to the value you're testing, not all 100+:
assert_that("hello").→ string methods:starts_with,matches,is_alpha, ...assert_that(42).→ numeric methods:is_positive,is_between,is_close_to, ...assert_that(Path("/tmp")).→ path methods:exists,is_file,is_readable, ...assert_that(my_dict).→ dict methods:contains_key,contains_entry,has_json_path, ...assert_that(b"\x89PNG").→ bytes methods:starts_with_bytes,is_valid_utf8,decoded_as, ...
9 type-specific Protocols instead of one Any. Works in PyCharm, VS Code, and any LSP-compatible editor.
Features
Fluent API
- Composable matchers:
match.greater_than(5),match.is_uuid(), combine with&,|,~. Also work with plainassert ==. - Structural matching:
matches_structure()for declarative dict/API response validation. - Universal negation:
.not_inverts any assertion without dedicatedis_not_*methods. - Collection pipeline:
filtered_on(),mapped(),flat_mapped(),first(),last(),element(),single(). - Fluent chaining: write assertions as readable one-liners that chain naturally.
Built-in types
- Strings, numbers, lists, tuples, sets, dicts, dates, booleans, objects, bytes, files, exceptions.
- Bytes assertions:
is_valid_utf8(),starts_with_bytes(),is_hex_equal_to(),decoded_as()forbytes/bytearray. - JSON assertions: JSONPath navigation and JSON Schema validation.
pip install assertpy2[json]. - Dynamic assertions:
has_<name>()for any attribute, property, or zero-argument method. - Dict comparison:
is_equal_to()withignoreandincludefor selective key/field matching (dicts, dataclasses, namedtuples, Pydantic models, attrs, plain objects). - Extracting: flatten collections on attributes with
filterandsortsupport.
Testing
- Soft assertions: thread-safe, async-safe via
contextvars. Group errors withsa.group(), or useassert_all(). - Async assertions:
eventually()with polling/retry for eventual consistency. - Structured errors:
AssertionFailurewith.actual,.expected,.diffattributes. - Rich pytest diffs: recursive structural diffs for lists, sets, strings, dicts, dataclasses, namedtuples, Pydantic models. Circular reference protection.
- Snapshot testing: store and compare data structures in JSON format.
Type safety
- Type-aware autocomplete: 9 Protocols, IDE shows only relevant methods per type.
- py.typed:
Selfreturn types, PEP 561 compliant (PEP 561).
Extensibility
- Custom matchers:
register_matcher()for domain-specific matchers, composable with&,|,~. - Regex group extraction:
extracting_group()andmatches_with_groups()for regex captures. - Extensions:
add_extension()for custom assertion methods.
Integrations
- Allure: auto-attach structured diff and actual/expected data to reports.
pip install assertpy2[allure]. - Behave: ready-made parameter types for step definitions.
pip install assertpy2[behave].
See the full API reference for all assertion methods, examples, and advanced features.
Integrations
Allure
When allure-pytest is installed, the pytest plugin auto-attaches structured failure data to Allure reports as JSON attachments.
pip install assertpy2[allure]
Three modes controlled via pytest.ini (or pyproject.toml):
| Mode | What is attached |
|---|---|
diff (default) |
Structured Diff JSON (path-level breakdown) |
full |
Structured Diff + actual/expected JSON |
off |
Nothing |
# pyproject.toml
[tool.pytest.ini_options]
assertpy2_allure = "full"
Behave
Ready-made parameter types for Behave step definitions:
pip install assertpy2[behave]
# in environment.py or steps/conftest.py
from assertpy2.behave_matchers import register_assertpy_types
register_assertpy_types()
Then use in step definitions:
@given('a user aged {age:PositiveInt}')
def step_impl(context, age):
context.age = age # already validated as int > 0
Available types: PositiveInt, NonNegativeInt, PositiveFloat, NonEmptyString, BoolLike.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file assertpy2-2.5.0.tar.gz.
File metadata
- Download URL: assertpy2-2.5.0.tar.gz
- Upload date:
- Size: 174.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3e8c6e935db358e45ae575cce7b8e8b12650a0573e32ba3600a33418c0739a02
|
|
| MD5 |
4677e9351a982fc67c6e1583167550f4
|
|
| BLAKE2b-256 |
89cb493c490cf38403834c3a1cbc29c29783ff96807fadbe0d76a4cd893574c9
|
Provenance
The following attestation bundles were made for assertpy2-2.5.0.tar.gz:
Publisher:
publish.yml on Solganis/assertpy2
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
assertpy2-2.5.0.tar.gz -
Subject digest:
3e8c6e935db358e45ae575cce7b8e8b12650a0573e32ba3600a33418c0739a02 - Sigstore transparency entry: 1861812703
- Sigstore integration time:
-
Permalink:
Solganis/assertpy2@99c106733f9ac562c136c6152729d487e8b22773 -
Branch / Tag:
refs/tags/v2.5.0 - Owner: https://github.com/Solganis
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@99c106733f9ac562c136c6152729d487e8b22773 -
Trigger Event:
release
-
Statement type:
File details
Details for the file assertpy2-2.5.0-py3-none-any.whl.
File metadata
- Download URL: assertpy2-2.5.0-py3-none-any.whl
- Upload date:
- Size: 61.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cd57630393a3d59baaa451d2737a885575e3ea4e6fdc7806c2f8a703c8073d00
|
|
| MD5 |
4a19410760c8f714384da39670b0307f
|
|
| BLAKE2b-256 |
edfab324f2ed9a6a4dd2081d4bff128d611e963fdaf4cbef92a63bf63d745e57
|
Provenance
The following attestation bundles were made for assertpy2-2.5.0-py3-none-any.whl:
Publisher:
publish.yml on Solganis/assertpy2
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
assertpy2-2.5.0-py3-none-any.whl -
Subject digest:
cd57630393a3d59baaa451d2737a885575e3ea4e6fdc7806c2f8a703c8073d00 - Sigstore transparency entry: 1861812776
- Sigstore integration time:
-
Permalink:
Solganis/assertpy2@99c106733f9ac562c136c6152729d487e8b22773 -
Branch / Tag:
refs/tags/v2.5.0 - Owner: https://github.com/Solganis
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@99c106733f9ac562c136c6152729d487e8b22773 -
Trigger Event:
release
-
Statement type: