Test equality of unordered collections in pytest
Project description
pytest-unordered: Test collection content, ignoring order
pytest_unordered
allows you to write simple (pytest) assertions
to test whether collections have the same content, regardless of order.
For example:
assert [1, 20, 300] == unordered([20, 300, 1])
Installation
pip install pytest-unordered
Usage
Basics
In most cases you just need the unordered()
helper function:
from pytest_unordered import unordered
Compare list or tuples by wrapping your expected value with unordered()
:
assert [1, 20, 300] == unordered([20, 300, 1]) # Pass
assert (1, 20, 300) == unordered((20, 300, 1)) # Pass
Excessive/missing items will be reported by pytest:
assert [1, 20, 300] == unordered([20, 300, 1, 300])
E Extra items in the right sequence:
E 300
By default, the container type has to match too:
assert (1, 20, 300) == unordered([20, 300, 1])
E Type mismatch:
E <class 'tuple'> != <class 'list'>
Nesting
A seasoned developer will notice that the simple use cases above
can also be addressed with appropriate usage
of builtins like set()
, sorted()
, isinstance()
, repr()
, etc,
but these solutions scale badly (in terms of boilerplate code)
with the complexity of your data structures.
For example: naively implementing order ignoring comparison
with set()
or sorted()
does not work with lists of dictionaries
because dictionaries are not hashable or sortable.
unordered()
supports this out of the box however:
assert [{"bb": 20}, {"a": 1}] == unordered([{"a": 1}, {"bb": 20}]) # Pass
The true value of unordered()
lies in the fact that you
can apply it inside large nested data structures to skip order checking
only in desired places with surgical precision
and without a lot of boilerplate code.
For example:
expected = unordered([
{"customer": "Alice", "orders": unordered([123, 456])},
{"customer": "Bob", "orders": [789, 1000]},
])
actual = [
{"customer": "Bob", "orders": [789, 1000]},
{"customer": "Alice", "orders": [456, 123]},
]
assert actual == expected
In this example we wrapped the outer customer list and the order list of Alice
with unordered()
, but didn't wrap Bob's order list.
With the actual
value of above (where customer order is different
and Alice's orders are reversed), the assertion will pass.
But if the orders of Bob would be swapped in actual
, the assertion
will fail and pytest will report:
E Differing items:
E {'orders': [1000, 789]} != {'orders': [789, 1000]}
Container type checking
As noted, the container types should be (by default) equal to pass the
assertion. If you don't want this type check, call unordered()
in a variable argument fashion (instead of passing
a container as single argument):
assert [1, 20, 300] == unordered(20, 300, 1) # Pass
assert (1, 20, 300) == unordered(20, 300, 1) # Pass
This pattern also allows comparing with iterators, generators and alike:
assert iter([1, 20, 300]) == unordered(20, 300, 1) # Pass
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
File details
Details for the file pytest-unordered-0.5.0.tar.gz
.
File metadata
- Download URL: pytest-unordered-0.5.0.tar.gz
- Upload date:
- Size: 4.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.1 CPython/3.8.13
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 05c1472afd2622efd407f2bae5e25adbb9a44ff32e07473186014c874c9b0f2e |
|
MD5 | bfcd852a874c1102b5602322ec56c03d |
|
BLAKE2b-256 | 9fcf7ae56fd5ceb6a78da3732c02838be1805d8e4f5c4a615edbc2c0ff10ac16 |
File details
Details for the file pytest_unordered-0.5.0-py3-none-any.whl
.
File metadata
- Download URL: pytest_unordered-0.5.0-py3-none-any.whl
- Upload date:
- Size: 5.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.1 CPython/3.8.13
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | a8dce78df40f0972b24b354299b56aebc4e671c223151ef11756182900febba3 |
|
MD5 | f92e7b3d098a0a30ee595691f7a16473 |
|
BLAKE2b-256 | a068ea81810caaed3b5ae938c563b2aec70d49c731b545c4edb692f5d108746e |