test_capture.py


Overview

The [test_capture.py](/projects/286/67356) file is a comprehensive test suite for the capturing facilities provided by the `_pytest.capture` module in the pytest testing framework. Capturing in pytest refers to intercepting output (stdout, stderr, and stdin) during test execution, allowing pytest to control, inspect, or suppress these streams for better test isolation and reporting.

This file validates the correctness, robustness, and integration of various capturing mechanisms including file descriptor capturing (`FDCapture`), system-level capturing (`SysCapture`), and combined capturing through `MultiCapture`. It also tests interactions with logging, fixture behavior, Unicode and binary output handling, error cases, and platform-specific workarounds.


Detailed Explanation of Key Components

Functions

StdCaptureFD(out: bool=True, err: bool=True, in_: bool=True) -> MultiCapture[str]

Creates a `MultiCapture` instance that captures standard input/output/error using file descriptor capturing (`FDCapture`) for fd 0 (stdin), 1 (stdout), and 2 (stderr), depending on the boolean flags.

StdCapture(out: bool=True, err: bool=True, in_: bool=True) -> MultiCapture[str]

Creates a `MultiCapture` instance that captures standard streams using system-level capturing (`SysCapture`) on fd 0,1,2 depending on flags.

TeeStdCapture(out: bool=True, err: bool=True, in_: bool=True) -> MultiCapture[str]

Creates a `MultiCapture` instance that captures output streams using system-level capturing (`SysCapture`) but with tee enabled, meaning captured output is also passed through to the original streams.


Classes

TestCaptureManager

Tests the `CaptureManager` class which manages global capturing modes (`no`, `sys`, and `fd`):

TestPerTestCapturing

Tests capturing on a per-test basis and interaction with setup and teardown fixtures:

TestLoggingInteraction

Tests interactions between capturing and Python's `logging` module:

TestCaptureFixture

Tests the pytest fixtures `capsys` and `capfd` which provide capturing functionality to tests:

TestCaptureIO and TestTeeCaptureIO

Unit tests for `CaptureIO` and `TeeCaptureIO` classes which implement in-memory stream capturing:

TestFDCapture

Tests for the `FDCapture` class which captures output at the file descriptor level:

TestStdCapture, TestTeeStdCapture, TestStdCaptureFD

These classes test `StdCapture`, `TeeStdCapture`, and `StdCaptureFD` respectively, verifying:


Important Implementation Details


Interaction With Other Parts of the System


Usage Examples

Using StdCapture to capture stdout and stderr

from test_capture import StdCapture

cap = StdCapture(out=True, err=True)
cap.start_capturing()
print("Hello stdout")
print("Hello stderr", file=sys.stderr)
out, err = cap.readouterr()
cap.stop_capturing()

assert out == "Hello stdout\n"
assert err == "Hello stderr\n"

Using capsys fixture in a pytest test

def test_output(capsys):
    print("Output")
    out, err = capsys.readouterr()
    assert out == "Output\n"
    assert err == ""

Disabling capture temporarily

def test_disabled_capture(capfd):
    print("Captured before")
    with capfd.disabled():
        print("Not captured")
    print("Captured after")
    out, err = capfd.readouterr()
    assert "Captured before" in out
    assert "Captured after" in out

Mermaid Class Diagram

classDiagram
    class TestCaptureManager {
        +test_capturing_basic_api(method)
        +test_init_capturing()
    }
    class TestPerTestCapturing {
        +test_capture_and_fixtures(pytester)
        +test_capture_scope_cache(pytester)
        +test_no_carry_over(pytester)
        +test_teardown_capturing(pytester)
        +test_teardown_capturing_final(pytester)
        +test_capturing_outerr(pytester)
    }
    class TestLoggingInteraction {
        +test_logging_stream_ownership(pytester)
        +test_logging_and_immediate_setupteardown(pytester)
        +test_logging_and_crossscope_fixtures(pytester)
        +test_conftestlogging_is_shown(pytester)
        +test_conftestlogging_and_test_logging(pytester)
        +test_logging_after_cap_stopped(pytester)
    }
    class TestCaptureFixture {
        +test_std_functional(pytester, opt)
        +test_capteesys(pytester)
        +test_capsyscapfd(pytester)
        +test_capturing_getfixturevalue(pytester)
        +test_capsyscapfdbinary(pytester)
        +test_capture_is_represented_on_failure_issue128(pytester, method)
        +test_stdfd_functional(pytester)
        +test_cafd_preserves_newlines(capfd, nl)
        +test_capfdbinary(pytester)
        +test_capsysbinary(pytester)
        +test_partial_setup_failure(pytester)
        +test_keyboardinterrupt_disables_capturing(pytester)
        +test_capture_and_logging(pytester)
        +test_disabled_capture_fixture(pytester, fixture, no_capture)
        +test_disabled_capture_fixture_twice(pytester)
        +test_fixture_use_by_other_fixtures(pytester, fixture)
        +test_fixture_use_by_other_fixtures_teardown(pytester, cap)
    }
    class TestCaptureIO {
        +test_text()
        +test_unicode_and_str_mixture()
        +test_write_bytes_to_buffer()
    }
    class TestTeeCaptureIO {
        +test_text()
        +test_unicode_and_str_mixture()
    }
    class TestFDCapture {
        +test_simple(tmpfile)
        +test_simple_many(tmpfile)
        +test_simple_many_check_open_files(pytester)
        +test_simple_fail_second_start(tmpfile)
        +test_stderr()
        +test_stdin()
        +test_writeorg(tmpfile)
        +test_simple_resume_suspend()
        +test_capfd_sys_stdout_mode(capfd)
    }
    class TestStdCapture {
        +test_capturing_done_simple()
        +test_capturing_reset_simple()
        +test_capturing_readouterr()
        +test_capture_results_accessible_by_attribute()
        +test_capturing_readouterr_unicode()
        +test_reset_twice_error()
        +test_capturing_modify_sysouterr_in_between()
        +test_capturing_error_recursive()
        +test_just_out_capture()
        +test_just_err_capture()
        +test_stdin_restored()
        +test_stdin_nulled_by_default()
    }
    class TestTeeStdCapture {
        +test_capturing_error_recursive()
    }
    class TestStdCaptureFD {
        +test_simple_only_fd(pytester)
        +test_intermingling()
        +test_many(capfd)
    }
    TestTeeStdCapture --|> TestStdCapture
    TestStdCaptureFD --|> TestStdCapture

Summary

The [test_capture.py](/projects/286/67356) file is a vital and extensive test suite for pytest's capture subsystem. It verifies that output capturing works correctly across multiple capture modes and scenarios, integrates properly with pytest's fixture and logging systems, handles binary and Unicode data, and behaves robustly under error conditions and platform-specific quirks.

This file ensures that pytest users can rely on consistent, isolated, and configurable capturing of test output streams, which is essential for clear test reporting and debugging.


End of Documentation