bean.test
bean.test is a tiny test framework.
Just enough to pick apart rotten beans.
Overview
With bean.test you get:
- A small, fluent assertion API.
- Test data generation helpers.
- Simple test registration and reporting.
- test discovery
from bean import test
@test.register()
def test_something():
test.expect(1 + 1).Equal(2)
Note:
To quickly inspect the public API:
python -c " import bean.test as bean for v in sorted(dir(bean)): print(f'- {v}') "
Installation
Using pip:
pip install --upgrade bean-test
Using curl (direct download):
curl -Ls \
https://raw.githubusercontent.com/numen-0/bean/main/bean-test/src/bean/test.py
Command Line
bean.test can be used directly as a test runner.
python -m bean.test tests/
By default, files matching *.py are discovered. Use --pattern to change the
pattern:
python -m bean.test tests/ --pattern "test_*.py"
Run only specific namespaces:
python -m bean.test tests/ -n unit integration
Note:
For more information, run:
python -m bean.test --help
API
This is a quick reference for the main API.
For full details, see the source code.
Test Registration
Tests can be registered under different namespaces.
@register("math")
def test_addition(): ...
@register("http")
def test_request(): ...
Data Generation
rand provides small helpers for generating and composing random test data.
from bean.test import rand
list(rand.cases( # generator for tuple[bool, tuple[str, int]]
rand(bool), # <- retrieve bool
rand.choice(*rand.product( # <- chose a tuple[str, int]
("a", "b", "c"),
(1, 2, 3),
)),
count=5,
seed=42,
))
The Lab
Lab is the singleton responsible for running tests and generating reports
| member | descrition |
|---|---|
report(ns) |
Generate report for all or the given namespaces |
print(ns) |
Generate a report and write it to stdout |
Expect Assertions
Fluent assertions for inspecting values.
| Method | Descrition |
|---|---|
| misc | - |
Set(value) |
Replace asserted value |
Map(fn) |
Transform asserted value |
MapEach(fn) |
Transform asserted value items |
Check(predicate) |
Assert value satisfies predicate |
| context | - |
Raises(exception) |
Context manager asserting that an exception is raised |
| turthiness | - |
Truthy() |
Assert value is truthy |
Falsy() |
Assert value is falsy |
Empty() |
Assert value has length zero |
NotEmpty() |
Assert value has non-zero length |
| equality | - |
Equal(expected) |
Assert value == expected |
NotEqual(expected) |
Assert value != expected |
Greater(expected) |
Assert value < expected |
GreaterEqual(expected) |
Assert value <= expected |
Less(expected) |
Assert value > expected |
LessEqual(expected) |
Assert value >= expected |
AlmostEqual(expected) |
Assert numeric values are approximately equal |
NotAlmostEqual(expected) |
Assert numeric values are not approximately equal |
| type identity | - |
Is(expected) |
Assert value is expected |
IsNot(expected) |
Assert value is not expected |
IsNone() |
Assert value is None |
IsNotNone() |
Assert value is not None |
IsInstance(cls) |
Assert value is an instance of a type |
IsNotInstance(cls) |
Assert value is not an instance of a type |
IsNumeric() |
Assert value is numeric |
IsString() |
Assert value is a string |
IsEnum() |
Assert value is a enum |
IsIterable() |
Assert value is iterable |
| strings | - |
StartsWith(expected) |
Assert value starts with given prefix |
NotStartsWith(expected) |
Assert value doesn't start with given prefix |
EndsWith(expected) |
Assert value ends with given suffix |
NotEndsWith(expected) |
Assert value doesn't end with given suffix |
Regex(expected) |
Assert value matches regular expression |
NotRegex(expected) |
Assert value doesn't matche regular expression |
| quantifiers | - |
All(predicate) |
Assert every item satisfies predicate |
Any(predicate) |
Assert at least one item satisfies predicate |
NotAny(predicate) |
Assert no item satisfies predicate |
IsSorted() |
Assert value is sorted |
| quantifiers | - |
In(expected) |
Assert value is contained in expected |
NotIn(expected) |
Assert value isn't contained in expected |
HasAttr(expected) |
Assert value has an attribute |
NotHasAttr(expected) |
Assert value hasn't an attribute |
| collections | - |
SequenceEqual(expected) |
Assert equal items in the same order |
ContainerEqual(expected) |
Assert equal items, ignoring order and preserving multiplicity |
SetEqual(expected) |
Assert equal items using set semantics |
NotSetEqual(expected) |
Assert containers are not set-equal |
Subset(expected) |
Assert every item is contained in expected |
NotSubset(expected) |
Assert at least one item is outside expected |
Superset(expected) |
Assert value contains every expected item |
NotSuperset(expected) |
Assert at least one expected item is missing |
Intersects(expected) |
Assert containers have no items in common |
Disjoint(expected) |
Assert containers have at least one item in common |
Note: Every method returns
self, so multiple assertions can be chained
Example
from bean import test
@test.register()
def test_addition():
test.expect(1 + 1).Equal(2)
@test.register()
def test_string():
test.expect("hello world") \
.IsString() \
.NotEmpty() \
.StartsWith("hello") \
.EndsWith("world")
@test.register()
def test_collections():
test.expect([1, 2, 3]).SequenceEqual([1, 2, 3])
test.expect([3, 1, 2]).SetEqual([1, 2, 3])
test.expect([1, 2]).Subset([1, 2, 3])
@test.register()
def test_exception():
with test.expect.Raises(ValueError):
int("bean")
test.Lab.print()
License
All the repo falls under the MIT License.
Metadata
Release files for bean-test 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| bean_test-0.1.0.tar.gz | 15.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| bean_test-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 28.0 kB
Release files / bean_test-0.1.0.tar.gz
| Download URL | bean_test-0.1.0.tar.gz |
|---|---|
| Size | 15.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0500b9b1db3d5970b7cabb4f48a94ae26a5148c347368b6fca0a8c0abdeca681
|
|
BLAKE2b-256 checksum How to use checksums |
811772e6fa03c8f144ce69a5e030721f11448ea404187107b65fa538fcd60e87
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 30, 2026.
Transparency logRelease files / bean_test-0.1.0-py3-none-any.whl
| Download URL | bean_test-0.1.0-py3-none-any.whl |
|---|---|
| Size | 12.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a875f20d8e7241715b2f71ef3bb040bf8c222c2700db73f15d0e18f99b8f01a4
|
|
BLAKE2b-256 checksum How to use checksums |
2375869c4ce65be8bc9a75e8821253e67e270ce6f10d82e62e413a3305a265ff
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 30, 2026.
Transparency log