From 1567b2cbd5cd1107dc9b9a838d2cd3b6baafeb20 Mon Sep 17 00:00:00 2001 From: Dustin Spicuzza Date: Sat, 21 Feb 2026 19:43:39 +0000 Subject: [PATCH] Fix isolated pytest assertion rendering in worker process --- .../pytest_isolated_tests_plugin.py | 27 +++++++++++++++++++ tests/test_pytest_plugins.py | 20 ++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/pyfrc/test_support/pytest_isolated_tests_plugin.py b/pyfrc/test_support/pytest_isolated_tests_plugin.py index 57852b3..f1d69c0 100644 --- a/pyfrc/test_support/pytest_isolated_tests_plugin.py +++ b/pyfrc/test_support/pytest_isolated_tests_plugin.py @@ -19,6 +19,24 @@ from .pytest_plugin import PyFrcPlugin +class _NullTerminalWriter: + def _highlight(self, source, lexer="python"): + return source + + +class _NullTerminalReporter: + """Minimal terminal reporter used in worker processes.""" + + def __init__(self): + self._tw = _NullTerminalWriter() + + def write(self, *args, **kwargs): + pass + + def line(self, *args, **kwargs): + pass + + def _enable_faulthandler(): # # In the event of a segfault, faulthandler will dump the currently @@ -67,6 +85,15 @@ def sendevent(self, name: str, **kwargs: object): @pytest.hookimpl(wrapper=True) def pytest_sessionstart(self, session: pytest.Session): self.config = session.config + + # When we disable terminalreporter in worker mode we still need a + # minimal reporter so assertion introspection can render diffs. + if self.config.pluginmanager.get_plugin("terminalreporter") is None: + self.config.pluginmanager.unblock("terminalreporter") + self.config.pluginmanager.register( + _NullTerminalReporter(), "terminalreporter" + ) + return (yield) @pytest.hookimpl diff --git a/tests/test_pytest_plugins.py b/tests/test_pytest_plugins.py index 1b22013..e5e84d9 100644 --- a/tests/test_pytest_plugins.py +++ b/tests/test_pytest_plugins.py @@ -177,6 +177,26 @@ def test_robot_failure_output(robot): assert robot_pid_one != robot_pid_two +def test_isolated_plugin_assertion_rendering(pytester): + _make_robot_module(pytester) + _configure_isolated_plugin(pytester) + pytester.makepyfile(test_isolated=""" +def test_robot_assertion_rendering(robot): + assert "x" == "y" +""") + + result = pytester.runpytest_subprocess("-vv") + + result.assert_outcomes(failed=1) + result.stdout.fnmatch_lines( + [ + "*test_isolated.py::test_robot_assertion_rendering FAILED*", + "*assert 'x' == 'y'*", + ] + ) + assert not any("_pytest/config/__init__.py" in line for line in result.outlines) + + def test_isolated_plugin_no_duplicate_verbose_output(pytester): _make_robot_module(pytester) _configure_isolated_plugin(pytester)