diff --git a/README.rst b/README.rst index cc47f0a..9bb42be 100644 --- a/README.rst +++ b/README.rst @@ -82,9 +82,7 @@ Here's an example of the output provided by the plugin when run with ======================= 1 failed, 2 rerun in 0.02 seconds ==================== Note that output will show all re-runs. Tests that fail on all the re-runs will -be marked as failed. Due to a -`current limitation in pytest-xdist `_, -when running tests in parallel only the final result will be included in the output. +be marked as failed. Compatibility ------------- diff --git a/pytest_rerunfailures.py b/pytest_rerunfailures.py index 1d7eb3f..f094b57 100644 --- a/pytest_rerunfailures.py +++ b/pytest_rerunfailures.py @@ -1,9 +1,27 @@ +import pkg_resources + import pytest from _pytest.runner import runtestprotocol from _pytest.resultlog import ResultLog +def works_with_current_xdist(): + """Returns compatibility with installed pytest-xdist version. + + When running tests in parallel using pytest-xdist < 1.20.0, the first + report that is logged will finish and terminate the current node rather + rerunning the test. Thus we must skip logging of intermediate results under + these circumstances, otherwise no test is rerun. + + """ + try: + d = pkg_resources.get_distribution('pytest-xdist') + return d.parsed_version >= pkg_resources.parse_version('1.20') + except pkg_resources.DistributionNotFound: + return None + + # command line options def pytest_addoption(parser): group = parser.getgroup( @@ -69,6 +87,8 @@ def pytest_runtest_protocol(item, nextitem): # first item if necessary check_options(item.session.config) + parallel = hasattr(item.config, 'slaveinput') + for i in range(reruns + 1): # ensure at least one run of each item item.ihook.pytest_runtest_logstart(nodeid=item.nodeid, location=item.location) @@ -84,14 +104,7 @@ def pytest_runtest_protocol(item, nextitem): # failure detected and reruns not exhausted, since i < reruns report.outcome = 'rerun' - # When running tests in parallel using pytest-xdist the first - # report that is logged will finish and terminate the current - # node rather rerunning the test. Thus we must skip logging of - # intermediate results when running in parallel, otherwise no - # test is rerun. - # See: https://github.com/pytest-dev/pytest/issues/1193 - parallel_testing = hasattr(item.config, 'slaveinput') - if not parallel_testing: + if not parallel or works_with_current_xdist(): # will rerun test, log intermediate result item.ihook.pytest_runtest_logreport(report=report) @@ -162,4 +175,3 @@ def pytest_runtest_logreport(self, report): longrepr = str(report.longrepr) self.log_outcome(report, code, longrepr) -