diff --git a/docs/user_guide.rst b/docs/user_guide.rst index 691c86f2..54a8d8e6 100644 --- a/docs/user_guide.rst +++ b/docs/user_guide.rst @@ -21,6 +21,14 @@ ini-value: [pytest] generate_report_on_test = True +If you have many tests report streaming may slow down pytest. You can limit how often +tests generate the report using ``generate_report_on_test_rate`` ini-value: + +.. code-block:: ini + + [pytest] + generate_report_on_test_rate = 1.0 + Creating a self-contained report -------------------------------- diff --git a/src/pytest_html/basereport.py b/src/pytest_html/basereport.py index cfcc74b2..0991ef76 100644 --- a/src/pytest_html/basereport.py +++ b/src/pytest_html/basereport.py @@ -35,6 +35,7 @@ def __init__(self, report_path, config, report_data, template, css): self._report = report_data self._report.title = self._report_path.name self._suite_start_time = time.time() + self._last_generated_time = None @property def css(self): @@ -49,14 +50,31 @@ def _asset_filename(self, test_id, extra_index, test_index, file_extension): file_extension, )[-self._max_asset_filename_length :] + def _should_generate_report_on_test(self): + if not self._config.getini("generate_report_on_test"): + return False + + if self._last_generated_time is None: + return True + + seconds = self._config.getini("generate_report_on_test_rate") + + if seconds == 0.0: + return True + + return ( + datetime.datetime.now() - self._last_generated_time + >= datetime.timedelta(seconds=seconds) + ) + def _generate_report(self, self_contained=False): - generated = datetime.datetime.now() + self._last_generated_time = datetime.datetime.now() test_data = self._report.data test_data = json.dumps(test_data) rendered_report = self._template.render( title=self._report.title, - date=generated.strftime("%d-%b-%Y"), - time=generated.strftime("%H:%M:%S"), + date=self._last_generated_time.strftime("%d-%b-%Y"), + time=self._last_generated_time.strftime("%H:%M:%S"), version=__version__, styles=self.css, run_count=self._run_count(), @@ -175,7 +193,7 @@ def pytest_sessionstart(self, session): self._report.table_header = _fix_py(headers) self._report.running_state = "started" - if self._config.getini("generate_report_on_test"): + if self._should_generate_report_on_test(): self._generate_report() @pytest.hookimpl(trylast=True) @@ -256,7 +274,7 @@ def pytest_runtest_logreport(self, report): dur = test_duration if when == "call" else each.duration self._process_report(each, dur, processed_extras) - if self._config.getini("generate_report_on_test"): + if self._should_generate_report_on_test(): self._generate_report() def _process_report(self, report, duration, processed_extras): diff --git a/src/pytest_html/plugin.py b/src/pytest_html/plugin.py index 949a6ffa..aacab991 100644 --- a/src/pytest_html/plugin.py +++ b/src/pytest_html/plugin.py @@ -79,6 +79,13 @@ def pytest_addoption(parser): help="the HTML report will be generated after each test " "instead of at the end of the run.", ) + parser.addini( + "generate_report_on_test_rate", + type="float", + default=0.0, + help="limit how often the report can be generated " + "expects a value in seconds", + ) def pytest_configure(config):