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
|
from __future__ import print_function
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import itertools
|
import collections
|
||||||
import platform
|
import platform
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
@ -727,33 +727,33 @@ class TerminalReporter(object):
|
||||||
|
|
||||||
final = hasattr(self, "_already_displayed_warnings")
|
final = hasattr(self, "_already_displayed_warnings")
|
||||||
if final:
|
if final:
|
||||||
warnings = all_warnings[self._already_displayed_warnings :]
|
warning_reports = all_warnings[self._already_displayed_warnings :]
|
||||||
else:
|
else:
|
||||||
warnings = all_warnings
|
warning_reports = all_warnings
|
||||||
self._already_displayed_warnings = len(warnings)
|
self._already_displayed_warnings = len(warning_reports)
|
||||||
if not warnings:
|
if not warning_reports:
|
||||||
return
|
return
|
||||||
|
|
||||||
grouped = itertools.groupby(
|
reports_grouped_by_message = collections.OrderedDict()
|
||||||
warnings, key=lambda wr: wr.get_location(self.config)
|
for wr in warning_reports:
|
||||||
)
|
reports_grouped_by_message.setdefault(wr.message, []).append(wr)
|
||||||
|
|
||||||
title = "warnings summary (final)" if final else "warnings summary"
|
title = "warnings summary (final)" if final else "warnings summary"
|
||||||
self.write_sep("=", title, yellow=True, bold=False)
|
self.write_sep("=", title, yellow=True, bold=False)
|
||||||
for location, warning_records in grouped:
|
for message, warning_reports in reports_grouped_by_message.items():
|
||||||
# legacy warnings show their location explicitly, while standard warnings look better without
|
has_any_location = False
|
||||||
# it because the location is already formatted into the message
|
for w in warning_reports:
|
||||||
warning_records = list(warning_records)
|
location = w.get_location(self.config)
|
||||||
if location:
|
|
||||||
self._tw.line(str(location))
|
|
||||||
for w in warning_records:
|
|
||||||
if location:
|
if location:
|
||||||
lines = w.message.splitlines()
|
self._tw.line(str(location))
|
||||||
indented = "\n".join(" " + x for x in lines)
|
has_any_location = True
|
||||||
message = indented.rstrip()
|
if has_any_location:
|
||||||
else:
|
lines = message.splitlines()
|
||||||
message = w.message.rstrip()
|
indented = "\n".join(" " + x for x in lines)
|
||||||
self._tw.line(message)
|
message = indented.rstrip()
|
||||||
|
else:
|
||||||
|
message = message.rstrip()
|
||||||
|
self._tw.line(message)
|
||||||
self._tw.line()
|
self._tw.line()
|
||||||
self._tw.line("-- Docs: https://docs.pytest.org/en/latest/warnings.html")
|
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)
|
warnings.warn("Message A", UserWarning)
|
||||||
with expectation:
|
with expectation:
|
||||||
warnings.warn("Message B", UserWarning)
|
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