cloudtools / cloudtools/troposphere
object comparison with pytest produces output that isn't very useful
- Dominant language
- Python
- Stars
- 4.9k
- Forks
- 1.4k
- PR merge metrics
- No merged PRs in 30d
Description
Opening to remind myself to contribute this when I get a chance unless someone beats me to it but also to discuss final formatting.
Using the following example code:
```python
"""Example."""
from troposphere import Tag, Tags
def test_tags() -> None:
"""Test tag comparison."""
assert Tags(Tag("a-tag", "test"), Tag("b-tag", "test")) == Tags(
Tag("a-tag", "test"), Tag("b-tag", "fail")
)
```
pytest will output the following for the failed assertion:
```text
def test_tags() -> None:
"""Test tag comparison."""
> assert Tags(Tag("a-tag", "test"), Tag("b-tag", "test")) == Tags(
Tag("a-tag", "test"), Tag("b-tag", "fail")
)
E AssertionError: assert ==
E + where = Tags(, )
E + where = Tag('a-tag', 'test')
E + and = Tag('b-tag', 'test')
E + and = Tags(, )
E + where = Tag('a-tag', 'test')
E + and = Tag('b-tag', 'fail')
```
This does not give a ton of easily useful info about where the comparison failed. It can be determined for this simple example because everything is defined in the test but for large, complex comparison it is not user friendly.
This experience can be improved by adding a `__repr__` method to the classes.
```python
class BaseAWSObject:
def __repr__(self) -> str:
return f"<{self.__module__}.{self.__class__.__name__}({self.to_dict()}) object at {hex(id(self))}>"
class AWSHelperFn:
def __repr__(self) -> str:
return f"<{self.__module__}.{self.__class__.__name__}({self.to_dict()}) object at {hex(id(self))}>"
```
This would produce an output of:
```
def test_tags() -> None:
"""Test tag comparison."""
> assert Tags(Tag("a-tag", "test"), Tag("b-tag", "test")) == Tags(
Tag("a-tag", "test"), Tag("b-tag", "fail")
)
E AssertionError: assert ==
E + where = Tags(, )
E + where = Tag('a-tag', 'test')
E + and = Tag('b-tag', 'test')
E + and = Tags(, )
E + where = Tag('a-tag', 'test')
E + and = Tag('b-tag', 'fail')
```
While it still does not show the exact item in the object that is failing, it does provide the data contained within the objects in the `AssertionError`.
----
The example implementation provided here mirrors the `<... object at ...>` notation of `object.__repr__()`. Should formatting be retained or should any part of it be dropped ` or just `object at ...`) or should the formatting remain as it is in the example above?
Contributor guide
Assessment
This issue has not been assessed yet.