diff --git a/changelog/6267.feature.rst b/changelog/6267.feature.rst new file mode 100644 index 00000000000..268ebc24130 --- /dev/null +++ b/changelog/6267.feature.rst @@ -0,0 +1,2 @@ +When output is close to truncation limit, we now write 'N lines hidden [1 truncated]', +instead of 'N+1 lines hidden' - last line which we show isn't really hidden always, neither it's always really truncated. diff --git a/src/_pytest/assertion/truncate.py b/src/_pytest/assertion/truncate.py index d97b05b441e..dc8fd3c4c2e 100644 --- a/src/_pytest/assertion/truncate.py +++ b/src/_pytest/assertion/truncate.py @@ -40,6 +40,8 @@ def _truncate_explanation(input_lines, max_lines=None, max_chars=None): Truncates to either 8 lines, or 640 characters - whichever the input reaches first. The remaining lines will be replaced by a usage message. + + Check https://github.com/pytest-dev/pytest/issues/6267 for corner cases """ if max_lines is None: @@ -62,12 +64,18 @@ def _truncate_explanation(input_lines, max_lines=None, max_chars=None): # Append useful message to explanation truncated_line_count = len(input_lines) - len(truncated_explanation) - truncated_line_count += 1 # Account for the part-truncated final line msg = "...Full output truncated" + last_truncated = not ( + input_lines[len(truncated_explanation) - 1] in truncated_explanation[-1] + ) if truncated_line_count == 1: - msg += " ({} line hidden)".format(truncated_line_count) + msg += " ({} line hidden".format(truncated_line_count) + else: + msg += " ({} lines hidden".format(truncated_line_count) + if last_truncated: + msg += ", 1 truncated)" else: - msg += " ({} lines hidden)".format(truncated_line_count) + msg += ")" msg += ", {}".format(USAGE_MSG) truncated_explanation.extend(["", str(msg)]) return truncated_explanation