Pytest: Rich comparison for attrs/dataclass classes?

Created on 28 Jun 2018  Â·  12Comments  Â·  Source: pytest-dev/pytest

Sooo, since I just ran into it myself: when I assert over classes, I obviously get an error similar to X(1) != X(2). Which once you have more than a handful of attributes becomes unreadable.

I usually use asdict temporarily and just do a assert attr.asdict(x) == attr.asdict(y) which will give me a nice diff. I know that other people also already did some hacking on this.

Now with attrs classes (and the upcoming dataclasses), it wouldn’t be too hard to give us nice, rich asserts: Once you detect inequality, you “just” have to check for (equal types obviously, and then) x.__attrs_attrs__, and if it exists pluck out attributes that are used for equality from there and find out which are actually not equal.

And ✨, you can tell the user exactly which attributes failed the equality test. Does that sound interesting for you at all? Now that 3.7 is out, I’m confident people will be interested in such a feature and IIRC, DCs and attrs are implemented similarly so both could/should be implemented at once.

easy enhancement feature-branch

Most helpful comment

Closed by #3776 🎉

All 12 comments

GitMate.io thinks possibly related issues are https://github.com/pytest-dev/pytest/issues/1476 (Comparison with unittest2), https://github.com/pytest-dev/pytest/issues/3381 (Remove use of attrs), https://github.com/pytest-dev/pytest/issues/484 (Order of class fixtures), https://github.com/pytest-dev/pytest/issues/2435 (f), and https://github.com/pytest-dev/pytest/issues/2618 (Propagating fixtures to test class attribute).

@hynek it would be a nice addition i believe

Definitely, it also seems simple as well: implement a pytest_assertrepr_compare hook which customizes the exception for attrs and dataclasses.

a initial iteration cold just use dict comparison for as_dict output of it

based on prior api this may be the most fun way to support namedtuples, dataclasses and attrs in one swoop - use asdict/_asdict

JFTR, asdict doesn’t take into account whether an attribute is part of equality checking. You could probably solve that using a filter tho.

@hynek oh, thats a important detail i had forgotten, thanks for bringing it to attention

since we use attrs ourself first class support is certainly desired ^^

since we use attrs ourself first class support is certainly desired ^^

That’s what I was hoping for. ;)

I'm looking into this issue.

Got a rough version of this working for both dataclasses and attrs classes.

Right now I'm using the pytest_assertrepr_compare hook in a conftest.py. Based on docs, I think I need to put my code in the _pytest directory; should I create a new file in the src._pytest.assertion package?

Thank you for your help!

Great @alysivji!

Creating a new file in src._pytest.assertion seems like a good start. Feel free to open a PR (targetting features) and we can discuss this better over the code. 👍

Closed by #3776 🎉

Was this page helpful?
0 / 5 - 0 ratings