Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

object comparison with pytest produces output that isn't very useful #2205

Open
ITProKyle opened this issue Nov 14, 2023 · 0 comments
Open

Comments

@ITProKyle
Copy link
Contributor

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:

"""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:

    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 <troposphere.Tags object at 0x1108fda90> == <troposphere.Tags object at 0x1108ff550>
E        +  where <troposphere.Tags object at 0x1108fda90> = Tags(<troposphere.Tag object at 0x110911ed0>, <troposphere.Tag object at 0x1108ff990>)
E        +    where <troposphere.Tag object at 0x110911ed0> = Tag('a-tag', 'test')
E        +    and   <troposphere.Tag object at 0x1108ff990> = Tag('b-tag', 'test')
E        +  and   <troposphere.Tags object at 0x1108ff550> = Tags(<troposphere.Tag object at 0x1108fdd10>, <troposphere.Tag object at 0x1108fd450>)
E        +    where <troposphere.Tag object at 0x1108fdd10> = Tag('a-tag', 'test')
E        +    and   <troposphere.Tag object at 0x1108fd450> = 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.

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 <troposphere.Tags([{'Key': 'a-tag', 'Value': 'test'}, {'Key': 'b-tag', 'Value': 'test'}]) object at 0x103653a50> == <troposphere.Tags([{'Key': 'a-tag', 'Value': 'test'}, {'Key': 'b-tag', 'Value': 'fail'}]) object at 0x103653b10>
E        +  where <troposphere.Tags([{'Key': 'a-tag', 'Value': 'test'}, {'Key': 'b-tag', 'Value': 'test'}]) object at 0x103653a50> = Tags(<troposphere.Tag({'Key': 'a-tag', 'Value': 'test'}) object at 0x1036539d0>, <troposphere.Tag({'Key': 'b-tag', 'Value': 'test'}) object at 0x103653810>)
E        +    where <troposphere.Tag({'Key': 'a-tag', 'Value': 'test'}) object at 0x1036539d0> = Tag('a-tag', 'test')
E        +    and   <troposphere.Tag({'Key': 'b-tag', 'Value': 'test'}) object at 0x103653810> = Tag('b-tag', 'test')
E        +  and   <troposphere.Tags([{'Key': 'a-tag', 'Value': 'test'}, {'Key': 'b-tag', 'Value': 'fail'}]) object at 0x103653b10> = Tags(<troposphere.Tag({'Key': 'a-tag', 'Value': 'test'}) object at 0x103653a90>, <troposphere.Tag({'Key': 'b-tag', 'Value': 'fail'}) object at 0x103653ad0>)
E        +    where <troposphere.Tag({'Key': 'a-tag', 'Value': 'test'}) object at 0x103653a90> = Tag('a-tag', 'test')
E        +    and   <troposphere.Tag({'Key': 'b-tag', 'Value': 'fail'}) object at 0x103653ad0> = 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 <e.g. just the <> or just object at ...) or should the formatting remain as it is in the example above?

@ITProKyle ITProKyle changed the title object comparison with pytest produces unuseful output object comparison with pytest produces output that isn't very useful Nov 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant