Package: pytest-iterassert
pytest-iterassertHave you ever wanted to usealloranyin 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 thepytesthelper for you!pytest-iterassertprovidesall_matchandany_matchto give you nice asserts.ExamplesThe built-inanyorallcan 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_matchandany_matchmake 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>)iterassertmakes 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_matchandany_matchtake no operator or operand.And, if you need to incorporate more transformations, but would like to see the
intermediary items,captureallows 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)Installationpytest-iterassert is on
PyPI, so you can simply install
viapip install pytest-iterassert(requires Python 3.6 or higher).(If you're really brave, you can also aliasall_matchandany_matchto the
builtin functions on import.)Changelog[0.0.3] - 2020-05-10Addcapture, and allowall_matchandany_matchto not take an
operator/operand, for checks inside the mapping function[0.0.2] - 2020-05-07Initial releaseDevelopmentThis library usesPoetryfor managing
dependencies. You just need to runpoetry install, and it will create a
virtual environment with all developer dependencies installed.Please runpoetry run ./lintbefore submitting pull requests.LicenseThis library is licensed under the Mozilla Public License Version 2.0. For more
information, seeLICENSE.