diff --git a/_pytest/hookspec.py b/_pytest/hookspec.py index 43667d701..f7b53e892 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 10f37c6a1..7dd10924a 100644 --- a/_pytest/terminal.py +++ b/_pytest/terminal.py @@ -323,6 +323,9 @@ class TerminalReporter: 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 @@ class TerminalReporter: 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 000000000..298892200 --- /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 26e1a8a69..3eb7d784e 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 bac3ab8b1..6b20c3a48 100644 --- a/testing/test_terminal.py +++ b/testing/test_terminal.py @@ -544,6 +544,23 @@ class TestTerminalFunctional(object): 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")