Skip to content

Commit

Permalink
Separate the various parts of the error report with newlines (#11659)
Browse files Browse the repository at this point in the history
Previously the error report would have all sections glued together:

- The assertion representation
- The error explanation
- The full diff

This makes it hard to see at a glance where which one starts and ends.

One of the representation (dataclasses, tuples, attrs) does display a
newlines at the start already.

Let's add a newlines before the error explanation and before the full
diff, so we get an easier to read report.

This has one disadvantage: we get one line less in the least verbose
mode, where the output gets truncated.
  • Loading branch information
BenjaminSchubert authored Dec 6, 2023
1 parent cd269f0 commit a536f49
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 23 deletions.
2 changes: 2 additions & 0 deletions changelog/11520.improvement.rst
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
Improved very verbose diff output to color it as a diff instead of only red.

Improved the error reporting to better separate each section.
4 changes: 3 additions & 1 deletion src/_pytest/assertion/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,8 @@ def assertrepr_compare(
if not explanation:
return None

if explanation[0] != "":
explanation = [""] + explanation
return [summary] + explanation


Expand Down Expand Up @@ -332,7 +334,7 @@ def _compare_eq_iterable(
left_formatting = PrettyPrinter().pformat(left).splitlines()
right_formatting = PrettyPrinter().pformat(right).splitlines()

explanation = ["Full diff:"]
explanation = ["", "Full diff:"]
# "right" is the expected base against which we compare "left",
# see https://github.com/pytest-dev/pytest/issues/3333
explanation.extend(
Expand Down
32 changes: 23 additions & 9 deletions testing/python/approx.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ def test_error_messages_native_dtypes(self, assert_approx_raises_regex):
2.0,
1.0,
[
"",
" comparison failed",
f" Obtained: {SOME_FLOAT}",
f" Expected: {SOME_FLOAT} ± {SOME_FLOAT}",
Expand All @@ -113,6 +114,7 @@ def test_error_messages_native_dtypes(self, assert_approx_raises_regex):
"c": 3000000.0,
},
[
r"",
r" comparison failed. Mismatched elements: 2 / 3:",
rf" Max absolute difference: {SOME_FLOAT}",
rf" Max relative difference: {SOME_FLOAT}",
Expand All @@ -130,6 +132,7 @@ def test_error_messages_native_dtypes(self, assert_approx_raises_regex):
"c": None,
},
[
r"",
r" comparison failed. Mismatched elements: 2 / 3:",
r" Max absolute difference: -inf",
r" Max relative difference: -inf",
Expand All @@ -143,6 +146,7 @@ def test_error_messages_native_dtypes(self, assert_approx_raises_regex):
[1.0, 2.0, 3.0, 4.0],
[1.0, 3.0, 3.0, 5.0],
[
r"",
r" comparison failed. Mismatched elements: 2 / 4:",
rf" Max absolute difference: {SOME_FLOAT}",
rf" Max relative difference: {SOME_FLOAT}",
Expand All @@ -156,6 +160,7 @@ def test_error_messages_native_dtypes(self, assert_approx_raises_regex):
(1, 2.2, 4),
(1, 3.2, 4),
[
r"",
r" comparison failed. Mismatched elements: 1 / 3:",
rf" Max absolute difference: {SOME_FLOAT}",
rf" Max relative difference: {SOME_FLOAT}",
Expand All @@ -169,6 +174,7 @@ def test_error_messages_native_dtypes(self, assert_approx_raises_regex):
[0.0],
[1.0],
[
r"",
r" comparison failed. Mismatched elements: 1 / 1:",
rf" Max absolute difference: {SOME_FLOAT}",
r" Max relative difference: inf",
Expand All @@ -187,6 +193,7 @@ def test_error_messages_numpy_dtypes(self, assert_approx_raises_regex):
a,
b,
[
r"",
r" comparison failed. Mismatched elements: 1 / 20:",
rf" Max absolute difference: {SOME_FLOAT}",
rf" Max relative difference: {SOME_FLOAT}",
Expand All @@ -209,6 +216,7 @@ def test_error_messages_numpy_dtypes(self, assert_approx_raises_regex):
]
),
[
r"",
r" comparison failed. Mismatched elements: 3 / 8:",
rf" Max absolute difference: {SOME_FLOAT}",
rf" Max relative difference: {SOME_FLOAT}",
Expand All @@ -224,6 +232,7 @@ def test_error_messages_numpy_dtypes(self, assert_approx_raises_regex):
np.array([0.0]),
np.array([1.0]),
[
r"",
r" comparison failed. Mismatched elements: 1 / 1:",
rf" Max absolute difference: {SOME_FLOAT}",
r" Max relative difference: inf",
Expand All @@ -241,6 +250,7 @@ def test_error_messages_invalid_args(self, assert_approx_raises_regex):
message = "\n".join(str(e.value).split("\n")[1:])
assert message == "\n".join(
[
" ",
" Impossible to compare arrays with different shapes.",
" Shapes: (2, 1) and (2, 2)",
]
Expand All @@ -251,6 +261,7 @@ def test_error_messages_invalid_args(self, assert_approx_raises_regex):
message = "\n".join(str(e.value).split("\n")[1:])
assert message == "\n".join(
[
" ",
" Impossible to compare lists with different sizes.",
" Lengths: 2 and 3",
]
Expand All @@ -264,6 +275,7 @@ def test_error_messages_with_different_verbosity(self, assert_approx_raises_rege
2.0,
1.0,
[
"",
" comparison failed",
f" Obtained: {SOME_FLOAT}",
f" Expected: {SOME_FLOAT} ± {SOME_FLOAT}",
Expand All @@ -277,15 +289,15 @@ def test_error_messages_with_different_verbosity(self, assert_approx_raises_rege
a,
b,
[
r" comparison failed. Mismatched elements: 20 / 20:",
rf" Max absolute difference: {SOME_FLOAT}",
rf" Max relative difference: {SOME_FLOAT}",
r" Index \| Obtained\s+\| Expected",
rf" \(0,\)\s+\| {SOME_FLOAT} \| {SOME_FLOAT} ± {SOME_FLOAT}",
rf" \(1,\)\s+\| {SOME_FLOAT} \| {SOME_FLOAT} ± {SOME_FLOAT}",
rf" \(2,\)\s+\| {SOME_FLOAT} \| {SOME_FLOAT} ± {SOME_FLOAT}...",
"",
rf"\s*...Full output truncated \({SOME_INT} lines hidden\), use '-vv' to show",
r"^ $",
r"^ comparison failed. Mismatched elements: 20 / 20:$",
rf"^ Max absolute difference: {SOME_FLOAT}$",
rf"^ Max relative difference: {SOME_FLOAT}$",
r"^ Index \| Obtained\s+\| Expected\s+$",
rf"^ \(0,\)\s+\| {SOME_FLOAT} \| {SOME_FLOAT} ± {SOME_FLOAT}e-{SOME_INT}$",
rf"^ \(1,\)\s+\| {SOME_FLOAT} \| {SOME_FLOAT} ± {SOME_FLOAT}e-{SOME_INT}\.\.\.$",
"^ $",
rf"^ ...Full output truncated \({SOME_INT} lines hidden\), use '-vv' to show$",
],
verbosity_level=0,
)
Expand All @@ -294,6 +306,7 @@ def test_error_messages_with_different_verbosity(self, assert_approx_raises_rege
a,
b,
[
r" ",
r" comparison failed. Mismatched elements: 20 / 20:",
rf" Max absolute difference: {SOME_FLOAT}",
rf" Max relative difference: {SOME_FLOAT}",
Expand Down Expand Up @@ -652,6 +665,7 @@ def test_dict_for_div_by_zero(self, assert_approx_raises_regex):
{"foo": 42.0},
{"foo": 0.0},
[
r"",
r" comparison failed. Mismatched elements: 1 / 1:",
rf" Max absolute difference: {SOME_FLOAT}",
r" Max relative difference: inf",
Expand Down
Loading

0 comments on commit a536f49

Please sign in to comment.