Merge pull request #4665 from nicoddemus/group-warnings-by-message

Group warnings by message instead of by test id
This commit is contained in:
Bruno Oliveira 2019-01-24 20:00:27 -02:00 committed by GitHub
commit 7ddfc04793
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 60 additions and 21 deletions

View File

@ -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.

View File

@ -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,33 +727,33 @@ 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)
if location:
self._tw.line(str(location))
for w in 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:
lines = w.message.splitlines()
indented = "\n".join(" " + x for x in lines)
message = indented.rstrip()
else:
message = w.message.rstrip()
self._tw.line(message)
self._tw.line(str(location))
has_any_location = True
if has_any_location:
lines = message.splitlines()
indented = "\n".join(" " + x for x in lines)
message = indented.rstrip()
else:
message = message.rstrip()
self._tw.line(message)
self._tw.line()
self._tw.line("-- Docs: https://docs.pytest.org/en/latest/warnings.html")

View File

@ -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()

View File

@ -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