diff --git a/src/_pytest/capture.py b/src/_pytest/capture.py index 6d98676be5f..33659fac952 100644 --- a/src/_pytest/capture.py +++ b/src/_pytest/capture.py @@ -1049,14 +1049,20 @@ def test_output(capteesys): assert captured.out == "hello\n" """ capman: CaptureManager = request.config.pluginmanager.getplugin("capturemanager") - capture_fixture = CaptureFixture( - SysCapture, request, config=dict(tee=True), _ispytest=True - ) - capman.set_fixture(capture_fixture) - capture_fixture._start() - yield capture_fixture - capture_fixture.close() - capman.unset_fixture() + if capman.is_globally_capturing(): + capture_fixture = CaptureFixture( + SysCapture, request, config=dict(tee=True), _ispytest=True + ) + capman.set_fixture(capture_fixture) + capture_fixture._start() + yield capture_fixture + capture_fixture.close() + capman.unset_fixture() + else: + # capteesys does nothing when global capturing is disabled. + # This is so that the "tee" part of cap-tee-sys is not + # implemented without the "cap" part. + yield CaptureFixture(SysCapture, request, _ispytest=True) @fixture diff --git a/testing/test_capture.py b/testing/test_capture.py index ffbc440e3bf..2ebd54b11f9 100644 --- a/testing/test_capture.py +++ b/testing/test_capture.py @@ -478,6 +478,30 @@ def test_one(capteesys): result.stdout.fnmatch_lines(["sTdoUt", "sTdeRr"]) # no tee, just reported assert not result.stderr.lines + def test_capteesys_no_global_capture(self, pytester: Pytester) -> None: + """When global capture is disabled (-s), capteesys should not duplicate output. + + It should pass output straight through (printed once) and capteesys.readouterr() + should return empty strings since no per-test capture is active. + """ + p = pytester.makepyfile( + """\ + import sys + + def test_one(capteesys): + print("sTdoUt") + print("sTdeRr", file=sys.stderr) + out, err = capteesys.readouterr() + assert out == "" + assert err == "" + """ + ) + # Run with -s to disable global capture; ensure each line appears exactly once + result = pytester.runpytest_subprocess(p, "-s", "--quiet", "--quiet") + assert result.ret == ExitCode.OK + assert result.stdout.str().count("sTdoUt") == 1 + assert result.stderr.str().count("sTdeRr") == 1 + def test_capsyscapfd(self, pytester: Pytester) -> None: p = pytester.makepyfile( """\