Skip to main content

License: MPL 2.0 Build codecov Code style: black

pytest-iterassert

Have you ever wanted to use all or any in a unit test, but found the assert message to be lacking? Do assertions on class attributes in collections almost make you wish you were coding in Java (with a nice assertion framework)? Then this is the pytest helper for you! pytest-iterassert provides all_match and any_match to give you nice asserts.

Examples

The built-in any or all can cause a lot of sadness when tests fail:

    def test_generator_without_iterassert() -> None:
>       assert all(i < 1 for i in range(3))
E       assert False
E        +  where False = all(<genexpr> at 0x10221a250>)

all_match and any_match make debugging easy by hoisting the comparison out, and printing meaningful debug:

    def test_generator_with_iterassert() -> None:
>       assert all_match(range(3)) < 1
E       assert all(0, 1, 2) < 1
E        +  where all(0, 1, 2) = all_match(range(0, 3))
E        +    where range(0, 3) = range(3)

How about a more complex example? Asserting attributes of a class instance is pretty common.

    def test_attr_of_classes_without_iterassert() -> None:
        foos = [Foo(1), Foo(2), Foo(3)]
>       assert all(foo.bar < 3 for foo in foos)
E       assert False
E        +  where False = all(<genexpr> at 0x10597ca50>)

iterassert makes it easy to apply functions to the iterable, and will convince pytest to show you the result of that function!

    def test_attr_of_classes_with_iterassert_1() -> None:
        foos = [Foo(1), Foo(2), Foo(3)]
>       assert all_match(foos, get_bar) < 3
E       assert all(9001, 9002, 9003) < 3
E        +  where all(9001, 9002, 9003) = all_match([<Foo(1)>, <Foo(2)>, <Foo(3)>], get_bar)

It's also possible to run more complex checks against all items, by doing the checking inside a function:

    def test_attr_of_classes_with_iterassert_2() -> None:
        foos = [Foo(1), Foo(2), Foo(3)]
>       assert all_match(foos, check_bar)
E       assert all(False, False, False)
E        +  where all(False, False, False) = all_match([<Foo(1)>, <Foo(2)>, <Foo(3)>], check_bar)

Note in this case, much like the buildin functions, all_match and any_match take no operator or operand.

And, if you need to incorporate more transformations, but would like to see the intermediary items, capture allows for this, too:

    def test_attr_of_classes_with_iterassert_3() -> None:
        foos = [Foo(1), Foo(2), Foo(3)]
>       assert all_match(capture(foo.bar for foo in foos), check_val)
E       assert all(False, False, False)
E        +  where all(False, False, False) = all_match([9001, 9002, 9003], check_val)
E        +    where [9001, 9002, 9003] = capture(<genexpr> at 0x1031220d0>)

Even the test summary says it all:

FAILED example.py::test_generator_without_iterassert - assert False
FAILED example.py::test_generator_with_iterassert - assert all(0, 1, 2) < 1
FAILED example.py::test_attr_of_classes_without_iterassert - assert False
FAILED example.py::test_attr_of_classes_with_iterassert_1 - assert all(9001, 9002, 9003) < 3
FAILED example.py::test_attr_of_classes_with_iterassert_2 - assert all(False, False, False)
FAILED example.py::test_attr_of_classes_with_iterassert_3 - assert all(False, False, False)

Installation

pytest-iterassert is on PyPI, so you can simply install via pip install pytest-iterassert (requires Python 3.6 or higher).

(If you're really brave, you can also alias all_match and any_match to the builtin functions on import.)

Changelog

[0.0.3] - 2020-05-10

  • Add capture, and allow all_match and any_match to not take an operator/operand, for checks inside the mapping function

[0.0.2] - 2020-05-07

  • Initial release

Development

This library uses Poetry for managing dependencies. You just need to run poetry install, and it will create a virtual environment with all developer dependencies installed.

Please run poetry run ./lint before submitting pull requests.

License

This library is licensed under the Mozilla Public License Version 2.0. For more information, see LICENSE.

Release files for pytest-iterassert 0.0.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pytest-iterassert 0.0.3
File Size Uploaded
pytest-iterassert-0.0.3.tar.gz 10.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pytest-iterassert 0.0.3
File Interpreter ABI Platform
pytest_iterassert-0.0.3-py3-none-any.whl Python 3 none any Details

Total release size: 19.4 kB

Release files / pytest-iterassert-0.0.3.tar.gz

Download URL pytest-iterassert-0.0.3.tar.gz
Size 10.0 kB
Tags Source
SHA-256 checksum
How to use checksums
eddca887060619e9ad132ce6b08d149737642a94c1ec90c1bdb7096d18f46f0b
BLAKE2b-256 checksum
How to use checksums
e6e492c97e0fdc6e9c1a84e8d77cc8de973bff5ae944ddb3ef9ba104e3cb9a5c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.0.5 CPython/3.6.10 Linux/5.0.0-1035-azure

Release files / pytest_iterassert-0.0.3-py3-none-any.whl

Download URL pytest_iterassert-0.0.3-py3-none-any.whl
Size 9.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8feec8968a6f4224d4af34c3dc036328c19210c946d0ad63971633b279929f40
BLAKE2b-256 checksum
How to use checksums
aeb8f028bbe582710ddbf2f413b38189b75001ea16b28abc691491fb8d8028fd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.0.5 CPython/3.6.10 Linux/5.0.0-1035-azure

Release history Release notifications | RSS feed

This release

0.0.3 This release

2 release files

0.0.2

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page