Feat: Add duration format hook (#724)

This commit is contained in:
Jim Brännlund 2023-09-01 20:14:10 +02:00 committed by GitHub
parent 372acd87f0
commit b7c50c137c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 50 additions and 2 deletions

View File

@ -304,6 +304,28 @@ Note that the values are case *sensitive*.
If tests are run in parallel (with `pytest-xdist`_ for example), then the order may not be
in the correct order.
Formatting the Duration Column
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The formatting of the timestamp used in the :code:`Durations` column can be modified by using the
:code:`pytest_html_duration_format` hook. The default timestamp will be `nnn ms` for durations
less than one second and `hh:mm:ss` for durations equal to or greater than one second.
Below is an example of a :code:`conftest.py` file setting :code:`pytest_html_duration_format`:
.. code-block:: python
import datetime
def pytest_html_duration_format(duration):
duration_timedelta = datetime.timedelta(seconds=duration)
time = datetime.datetime(1, 1, 1) + duration_timedelta
return time.strftime("%H:%M:%S")
**NOTE**: The behavior of sorting the duration column is not guaranteed when providing a custom format.
**NOTE**: The formatting of the total duration is not affected by this hook.
.. _@pytest.hookimpl(tryfirst=True): https://docs.pytest.org/en/stable/writing_plugins.html#hook-function-ordering-call-example
.. _ansi2html: https://pypi.python.org/pypi/ansi2html/

View File

@ -197,12 +197,19 @@ class BaseReport:
def pytest_runtest_logreport(self, report):
if hasattr(report, "duration_formatter"):
warnings.warn(
"'duration_formatter' has been removed and no longer has any effect!",
"'duration_formatter' has been removed and no longer has any effect!"
"Please use the 'pytest_html_duration_format' hook instead.",
DeprecationWarning,
)
outcome = _process_outcome(report)
duration = _format_duration(report.duration)
try:
# hook returns as list for some reason
duration = self._config.hook.pytest_html_duration_format(
duration=report.duration
)[0]
except IndexError:
duration = _format_duration(report.duration)
self._report.total_duration += report.duration
test_id = report.nodeid

View File

@ -21,3 +21,7 @@ def pytest_html_results_table_row(report, cells):
def pytest_html_results_table_html(report, data):
"""Called after building results table additional HTML."""
def pytest_html_duration_format(duration):
"""Called before using the default duration formatting."""

View File

@ -156,6 +156,21 @@ class TestHTML:
assert_that(duration).matches(expectation)
assert_that(total_duration).matches(r"\d{2}:\d{2}:\d{2}")
def test_duration_format_hook(self, pytester):
pytester.makeconftest(
"""
def pytest_html_duration_format(duration):
return str(round(duration * 1000)) + " seconds"
"""
)
pytester.makepyfile("def test_pass(): pass")
page = run(pytester)
assert_results(page, passed=1)
duration = get_text(page, "#results-table td[class='col-duration']")
assert_that(duration).contains("seconds")
def test_total_number_of_tests_zero(self, pytester):
page = run(pytester)
assert_results(page)