test_runner.py


Overview

The [test_runner.py](/projects/286/67339) file is a comprehensive test suite for various aspects of the `pytest` testing framework, focusing primarily on the test execution, setup and teardown mechanisms, reporting, and integration of specific pytest features such as [importorskip](/projects/286/67385), outcome exceptions, and environment variable management during tests.

This file contains a collection of test classes and standalone test functions that validate the internal workings and user-facing behaviors of pytest's test runner system. It ensures that test setup and teardown states are correctly handled, that test outcomes (pass, fail, skip) are properly reported, and that pytest hooks and exceptions behave as expected.


Classes and Their Functionality

1. TestSetupState

This class contains tests that verify the correctness of pytest's internal `SetupState` management, which is responsible for setting up test environments, managing finalizers, and tearing down tests.


2. BaseFunctionalTests

This class contains functional tests that simulate real test runs using `pytester` to validate outcomes and reporting.


3. TestExecutionNonForked(BaseFunctionalTests)

Subclass of `BaseFunctionalTests` that overrides the test runner to use [runtestprotocol](/projects/286/67543) directly without forking subprocesses.


4. TestSessionReports

Tests around session-level report collection.


5. TestReportContents

Tests the user-level API of pytest's `TestReport` objects.


6. TestImportOrSkipExcType

Tests related to the behavior of [pytest.importorskip](/projects/286/67385) and its interaction with import errors and warnings.


Important Functions and Tests (Standalone)


Implementation Details and Algorithms


Interactions with Other Parts of the System

Overall, this file ensures the robustness of pytest's test execution and reporting machinery, critical for reliable test runs.


Usage Examples

# Example: Running a test function and checking it passes
def test_passfunction_example(pytester: Pytester) -> None:
    reports = pytester.runitem("def test_func(): pass")
    rep = reports[1]
    assert rep.passed
    assert rep.outcome == "passed"

# Example: Adding a finalizer and checking it runs during teardown
def test_finalizer_runs(pytester: Pytester) -> None:
    item = pytester.getitem("def test_func(): pass")
    ss = item.session._setupstate
    ss.setup(item)
    called = []
    ss.addfinalizer(lambda: called.append(True), item)
    ss.teardown_exact(None)
    assert called == [True]

Mermaid Class Diagram

classDiagram
    class TestSetupState {
        +test_setup(pytester)
        +test_teardown_exact_stack_empty(pytester)
        +test_setup_fails_and_failure_is_cached(pytester)
        +test_teardown_multiple_one_fails(pytester)
        +test_teardown_multiple_fail(pytester)
        +test_teardown_multiple_scopes_one_fails(pytester)
        +test_teardown_multiple_scopes_several_fail(pytester)
        +test_cached_exception_doesnt_get_longer(pytester)
    }

    class BaseFunctionalTests {
        +test_passfunction(pytester)
        +test_failfunction(pytester)
        +test_skipfunction(pytester)
        +test_skip_in_setup_function(pytester)
        +test_failure_in_setup_function(pytester)
        +test_failure_in_teardown_function(pytester)
        +test_custom_failure_repr(pytester)
        +test_teardown_final_returncode(pytester)
        +test_logstart_logfinish_hooks(pytester)
        +test_exact_teardown_issue90(pytester)
        +test_exact_teardown_issue1206(pytester)
        +test_failure_in_setup_function_ignores_custom_repr(pytester)
        +test_systemexit_does_not_bail_out(pytester)
        +test_exit_propagates(pytester)
    }

    class TestExecutionNonForked {
        +getrunner()
        +test_keyboardinterrupt_propagates(pytester)
    }
    TestExecutionNonForked --|> BaseFunctionalTests

    class TestSessionReports {
        +test_collect_result(pytester)
    }

    class TestReportContents {
        +test_longreprtext_pass(pytester)
        +test_longreprtext_skip(pytester)
        +test_longreprtext_collect_skip(pytester)
        +test_longreprtext_failure(pytester)
        +test_captured_text(pytester)
        +test_no_captured_text(pytester)
        +test_longrepr_type(pytester)
    }

    class TestImportOrSkipExcType {
        +test_no_warning()
        +test_import_error_with_warning(pytester)
        +test_import_error_suppress_warning(pytester)
        +test_warning_integration(pytester)
    }

Summary

[test_runner.py](/projects/286/67339) is a vital internal test module for the pytest framework itself, designed to rigorously verify the correctness of test execution, setup/teardown logic, reporting, exception handling, and helper functions like [importorskip](/projects/286/67385). By testing both pytest internals and user-facing behaviors, it helps maintain pytest's reliability and feature correctness across versions and Python environments. It interacts closely with pytest's core classes and hooks, using the `pytester` utility to simulate test runs programmatically and capture their outcomes.