-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Better diff for asserts on dicts #1531
Comments
would you like to turn that into a pull request? also note, that for "proper" diff of nested structures one needs a path to the object being diffed as well |
I'd love to, but I can't seem to figure out the correct way to run pytest from source. |
I usually do something like:
And to run the tests/linters, simply run |
I'd also be interested in this :) |
I've had a good look at this recently, and it turns out to be a way bigger project than I had initially estimated. I'm afraid I can't quite find the time to get this done. sorry. |
No problem, thanks for the heads up. |
I am interested in tackling this. Just now starting to look into it. |
Just to add to this old (but important to me!) issue - it seems if you call |
@four43 That is unrelated to this issue and intended - pytest's assertion introspection/rewriting is only active for See the docs for details: |
Hey okay that's pretty slick. Thanks for the tip, I bet that solves my problem. I appreciate it. |
Just for the record (and inspiration) there are two pytest plugins that prints better dict comparisons: Source: https://eshlox.net/2020/04/07/better-diffs-in-pytest |
Thanks @m-aciek, I had a few minutes so I tried
Style aside, the diff is readable to me. While at it decided to take a stab at @SuperDoxin's idea of using json+difflib (using the same data sample from
Here's the output:
I like it too, but this has the problematic downside that json doesn't handle custom objects, and AFAIK there's no easy way to generalize it. |
When unit testing diagd most of the tests us the `econf_compile` helper which by default will assert that no aconf errors existed. This is good but it requires puttng a debugger on it to grab the errors. This prints out the object so that when the test is run outside of an IDE with a debugger the errors can be seen. Altough its not neatly diffed/printed due to being a nested structure. There is an issue to improve this but looks to be still open: pytest-dev/pytest#1531. Signed-off-by: Lance Austin <[email protected]>
* testing: provide assertion message for aconf errors When unit testing diagd most of the tests us the `econf_compile` helper which by default will assert that no aconf errors existed. This is good but it requires puttng a debugger on it to grab the errors. This prints out the object so that when the test is run outside of an IDE with a debugger the errors can be seen. Altough its not neatly diffed/printed due to being a nested structure. There is an issue to improve this but looks to be still open: pytest-dev/pytest#1531. * fix: envoy config generate when Host.hostname includes port When trying to expose a Host with a hostname that includes a port such as 'example.com:8500', causes 404 NR's due to the way envoy was configured. In the v1.14, we used to group everything under a wildcard virtual_host domain "*" and did not include sni matching on the Filter Chain. This allowed that configuration to work but had the downside of causing large memory usage and slower route matching due to lumping all routes into a single virtual host. If the v2.Y and v3.Y, series this was addressed by creating seperate Filter Chains for each host. A non-tls Host would get a single Filter Chain with multiple virtual_hosts per Host. A Host with TLS would produce a 1-1 FilterChain and Virtualhost. This works fine in most cases when downstream clients are connecting on standard ports (80/443) but when a client needs to connect on something like example.com:8500 this would effectively generate a Filter Chain that could never match on an incoming request. In the non-tls scenario there are no changes to what gets generated. In the TLS scenario we now parse the hostname into two entites, sni and virtual_host.domain. So, example.com:8500 would have an sni of example.com and a virtual_host.domain of example.com:8500. We create a Filter Chain for the sni value and add a virtual host for the domain value. If a second Host with just `example.com` is provided as well then we will attempt to merge these into a single Filter Chain with multiple virtual_host. We can only do this when the same TLSContext is used because we wouldn't know which attributes to take from which host since all the transport_socket settings are at the Filter Chain level. This restores existing behavior in a backwards compatiabile way and doesn't try to solve the Developer Experience (DX) with the way the Host is currently designed. Signed-off-by: Lance Austin <[email protected]>
@nicoddemus I believe the reason to use json dumping here is that the json output will format the diff with consistent If so, I believe it should be doable to extend/override the pretty printer used by pytest to have the same behavior. It might be quite some code due to how the PrettyPrinter is implemented, but would continue to work as today for everything else. I'd be happy to attempt a solution with prettyprinter if no-one is actively working on this and pytest would be fine with that added code |
Exactly. 👍
That would be amazing!
Oh yes, please go ahead, thanks a lot. |
#11537 would be my proposed solution |
Currently in some edge cases py.test returns utterly useless diffs for asserts on dicts, it doesn't provide the context needed to find which parts are differing in deeply nested dicts.
A better, and simpler, solution would be to use a json serializer to serialize the dicts and then use difflibs unified diff to generate the final diff. this solution will produce a diff in an easy to read format that people are familiar with and provides enough context to find the right place in the dict where changes need to be made.
any objects not json serializable in the dict can be adequately dealt with by using repr as serializer.
this whole function could be replaced with ~5 lines of code.
The text was updated successfully, but these errors were encountered: