Skip to main content

Test equality of unordered collections in pytest

Project description

pytest-unordered: Test collection content, ignoring order

Build Status Coverage Status

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pytest-unordered-0.5.0.tar.gz (4.8 kB view details)

Uploaded Source

Built Distribution

pytest_unordered-0.5.0-py3-none-any.whl (5.0 kB view details)

Uploaded Python 3

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

Hashes for pytest-unordered-0.5.0.tar.gz
Algorithm Hash digest
SHA256 05c1472afd2622efd407f2bae5e25adbb9a44ff32e07473186014c874c9b0f2e
MD5 bfcd852a874c1102b5602322ec56c03d
BLAKE2b-256 9fcf7ae56fd5ceb6a78da3732c02838be1805d8e4f5c4a615edbc2c0ff10ac16

See more details on using hashes here.

File details

Details for the file pytest_unordered-0.5.0-py3-none-any.whl.

File metadata

File hashes

Hashes for pytest_unordered-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a8dce78df40f0972b24b354299b56aebc4e671c223151ef11756182900febba3
MD5 f92e7b3d098a0a30ee595691f7a16473
BLAKE2b-256 a068ea81810caaed3b5ae938c563b2aec70d49c731b545c4edb692f5d108746e

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page