From 17c544e793f95a7e0423114a435ff51c17e8ad5e Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Thu, 27 Jul 2017 10:34:49 -0300 Subject: [PATCH] Introduce new pytest_report_collectionfinish hook Fix #2622 --- _pytest/hookspec.py | 16 +++++++++++++++- _pytest/terminal.py | 10 ++++++---- changelog/2622.feature | 2 ++ doc/en/writing_plugins.rst | 1 + testing/test_terminal.py | 17 +++++++++++++++++ 5 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 changelog/2622.feature diff --git a/_pytest/hookspec.py b/_pytest/hookspec.py index 43667d701c2..f7b53e892d8 100644 --- a/_pytest/hookspec.py +++ b/_pytest/hookspec.py @@ -337,7 +337,10 @@ def pytest_assertrepr_compare(config, op, left, right): def pytest_report_header(config, startdir): - """ return a string to be displayed as header info for terminal reporting. + """ return a string or list of strings to be displayed as header info for terminal reporting. + + :param config: the pytest config object. + :param startdir: py.path object with the starting dir .. note:: @@ -347,6 +350,17 @@ def pytest_report_header(config, startdir): """ +def pytest_report_collectionfinish(config, startdir, items): + """ return a string or list of strings to be displayed after collection has finished successfully. + + This strings will be displayed after the standard "collected X items" message. + + :param config: the pytest config object. + :param startdir: py.path object with the starting dir + :param items: list of pytest items that are going to be executed; this list should not be modified. + """ + + @hookspec(firstresult=True) def pytest_report_teststatus(report): """ return result-category, shortletter and verbose word for reporting. diff --git a/_pytest/terminal.py b/_pytest/terminal.py index 10f37c6a137..7dd10924ae6 100644 --- a/_pytest/terminal.py +++ b/_pytest/terminal.py @@ -323,6 +323,9 @@ def pytest_sessionstart(self, session): self.write_line(msg) lines = self.config.hook.pytest_report_header( config=self.config, startdir=self.startdir) + self._write_report_lines_from_hooks(lines) + + def _write_report_lines_from_hooks(self, lines): lines.reverse() for line in flatten(lines): self.write_line(line) @@ -349,10 +352,9 @@ def pytest_collection_finish(self, session): rep.toterminal(self._tw) return 1 return 0 - if not self.showheader: - return - # for i, testarg in enumerate(self.config.args): - # self.write_line("test path %d: %s" %(i+1, testarg)) + lines = self.config.hook.pytest_report_collectionfinish( + config=self.config, startdir=self.startdir, items=session.items) + self._write_report_lines_from_hooks(lines) def _printcollecteditems(self, items): # to print out items and their parent collectors diff --git a/changelog/2622.feature b/changelog/2622.feature new file mode 100644 index 00000000000..2988922004c --- /dev/null +++ b/changelog/2622.feature @@ -0,0 +1,2 @@ +New ``pytest_report_collectionfinish`` hook which allows plugins to add messages to the terminal reporting after +collection has been finished successfully. diff --git a/doc/en/writing_plugins.rst b/doc/en/writing_plugins.rst index 26e1a8a695b..3eb7d784ef5 100644 --- a/doc/en/writing_plugins.rst +++ b/doc/en/writing_plugins.rst @@ -644,6 +644,7 @@ Session related reporting hooks: .. autofunction:: pytest_collectreport .. autofunction:: pytest_deselected .. autofunction:: pytest_report_header +.. autofunction:: pytest_report_collectionfinish .. autofunction:: pytest_report_teststatus .. autofunction:: pytest_terminal_summary .. autofunction:: pytest_fixture_setup diff --git a/testing/test_terminal.py b/testing/test_terminal.py index bac3ab8b128..6b20c3a487b 100644 --- a/testing/test_terminal.py +++ b/testing/test_terminal.py @@ -544,6 +544,23 @@ def test_more_quiet_reporting(self, testdir): assert "===" not in s assert "passed" not in s + def test_report_collectionfinish_hook(self, testdir): + testdir.makeconftest(""" + def pytest_report_collectionfinish(config, startdir, items): + return ['hello from hook: {0} items'.format(len(items))] + """) + testdir.makepyfile(""" + import pytest + @pytest.mark.parametrize('i', range(3)) + def test(i): + pass + """) + result = testdir.runpytest() + result.stdout.fnmatch_lines([ + "collected 3 items", + "hello from hook: 3 items", + ]) + def test_fail_extra_reporting(testdir): testdir.makepyfile("def test_this(): assert 0")