Merge pull request #4665 from nicoddemus/group-warnings-by-message
Group warnings by message instead of by test id
This commit is contained in:
commit
7ddfc04793
|
@ -0,0 +1,4 @@
|
|||
Warning summary now groups warnings by message instead of by test id.
|
||||
|
||||
This makes the output more compact and better conveys the general idea of how much code is
|
||||
actually generating warnings, instead of how many tests call that code.
|
|
@ -7,7 +7,7 @@ from __future__ import division
|
|||
from __future__ import print_function
|
||||
|
||||
import argparse
|
||||
import itertools
|
||||
import collections
|
||||
import platform
|
||||
import sys
|
||||
import time
|
||||
|
@ -727,32 +727,32 @@ class TerminalReporter(object):
|
|||
|
||||
final = hasattr(self, "_already_displayed_warnings")
|
||||
if final:
|
||||
warnings = all_warnings[self._already_displayed_warnings :]
|
||||
warning_reports = all_warnings[self._already_displayed_warnings :]
|
||||
else:
|
||||
warnings = all_warnings
|
||||
self._already_displayed_warnings = len(warnings)
|
||||
if not warnings:
|
||||
warning_reports = all_warnings
|
||||
self._already_displayed_warnings = len(warning_reports)
|
||||
if not warning_reports:
|
||||
return
|
||||
|
||||
grouped = itertools.groupby(
|
||||
warnings, key=lambda wr: wr.get_location(self.config)
|
||||
)
|
||||
reports_grouped_by_message = collections.OrderedDict()
|
||||
for wr in warning_reports:
|
||||
reports_grouped_by_message.setdefault(wr.message, []).append(wr)
|
||||
|
||||
title = "warnings summary (final)" if final else "warnings summary"
|
||||
self.write_sep("=", title, yellow=True, bold=False)
|
||||
for location, warning_records in grouped:
|
||||
# legacy warnings show their location explicitly, while standard warnings look better without
|
||||
# it because the location is already formatted into the message
|
||||
warning_records = list(warning_records)
|
||||
for message, warning_reports in reports_grouped_by_message.items():
|
||||
has_any_location = False
|
||||
for w in warning_reports:
|
||||
location = w.get_location(self.config)
|
||||
if location:
|
||||
self._tw.line(str(location))
|
||||
for w in warning_records:
|
||||
if location:
|
||||
lines = w.message.splitlines()
|
||||
has_any_location = True
|
||||
if has_any_location:
|
||||
lines = message.splitlines()
|
||||
indented = "\n".join(" " + x for x in lines)
|
||||
message = indented.rstrip()
|
||||
else:
|
||||
message = w.message.rstrip()
|
||||
message = message.rstrip()
|
||||
self._tw.line(message)
|
||||
self._tw.line()
|
||||
self._tw.line("-- Docs: https://docs.pytest.org/en/latest/warnings.html")
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
import warnings
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
def func():
|
||||
warnings.warn(UserWarning("foo"))
|
||||
|
||||
|
||||
@pytest.mark.parametrize("i", range(5))
|
||||
def test_foo(i):
|
||||
func()
|
||||
|
||||
|
||||
def test_bar():
|
||||
func()
|
|
@ -693,3 +693,22 @@ def test_warnings_checker_twice():
|
|||
warnings.warn("Message A", UserWarning)
|
||||
with expectation:
|
||||
warnings.warn("Message B", UserWarning)
|
||||
|
||||
|
||||
@pytest.mark.filterwarnings("always")
|
||||
def test_group_warnings_by_message(testdir):
|
||||
testdir.copy_example("warnings/test_group_warnings_by_message.py")
|
||||
result = testdir.runpytest()
|
||||
result.stdout.fnmatch_lines(
|
||||
[
|
||||
"test_group_warnings_by_message.py::test_foo[0]",
|
||||
"test_group_warnings_by_message.py::test_foo[1]",
|
||||
"test_group_warnings_by_message.py::test_foo[2]",
|
||||
"test_group_warnings_by_message.py::test_foo[3]",
|
||||
"test_group_warnings_by_message.py::test_foo[4]",
|
||||
"test_group_warnings_by_message.py::test_bar",
|
||||
]
|
||||
)
|
||||
warning_code = 'warnings.warn(UserWarning("foo"))'
|
||||
assert warning_code in result.stdout.str()
|
||||
assert result.stdout.str().count(warning_code) == 1
|
||||
|
|
Loading…
Reference in New Issue