Integration with Other Test Frameworks

This module provides seamless integration of other Python test frameworks—specifically the standard library’s **unittest** framework and **doctest**—into the pytest testing ecosystem. Its purpose is to allow users to run tests written in these formats alongside native pytest tests, benefiting from pytest’s rich features such as fixture injection, detailed reporting, and test selection, without modifying existing unittest or doctest test code.


Overview

Integration with other test frameworks addresses the challenge of supporting legacy or alternative test styles transparently within pytest. This module enables pytest to:


Unittest Integration

Purpose and Problems Solved

The unittest integration allows pytest to recognize classes derived from `unittest.TestCase` and collect their test methods as pytest test items. This enables users to run existing unittest tests without rewriting them and to leverage pytest’s advanced features such as fixtures and plugins on these tests.

How It Works

Interaction with Other Parts of the System

Code Snippet Illustration

def pytest_pycollect_makeitem(collector, name, obj):
    # Detect unittest.TestCase subclasses for collection
    if issubclass(obj, unittest.TestCase) and not inspect.isabstract(obj):
        return UnitTestCase.from_parent(collector, name=name, obj=obj)

class UnitTestCase(Class):
    def collect(self):
        # Use unittest's TestLoader to discover test methods
        loader = unittest.TestLoader()
        for name in loader.getTestCaseNames(self.obj):
            yield TestCaseFunction.from_parent(self, name=name)

    def _register_unittest_setup_class_fixture(self, cls):
        # Register autouse fixture to run setUpClass and tearDownClass
        self.session._fixturemanager._register_fixture(
            name=f"_unittest_setUpClass_fixture_{cls.__qualname__}",
            func=unittest_setup_class_fixture,
            scope="class",
            autouse=True,
        )

Doctest Support

Purpose and Problems Solved

The doctest support enables pytest to automatically discover and run doctests found within Python modules or external text files. Doctests validate code examples embedded in docstrings or documentation, ensuring examples remain accurate and executable. This integration:

How It Works

Interaction with Other Parts of the System

Code Snippet Illustration

def pytest_collect_file(file_path, parent):
    if file_path.suffix == ".py" and parent.config.option.doctestmodules:
        return DoctestModule.from_parent(parent, path=file_path)
    elif _is_doctest(parent.config, file_path, parent):
        return DoctestTextfile.from_parent(parent, path=file_path)

class DoctestItem(Item):
    def setup(self):
        # Inject fixtures into doctest globals before running
        self._request._fillfixtures()
        self.dtest.globs.update(self._request.getfixturevalue("doctest_namespace"))

    def runtest(self):
        failures = []
        self.runner.run(self.dtest, out=failures)
        if failures:
            raise MultipleDoctestFailures(failures)

Summary of Key Concepts and Design Patterns


Mermaid Sequence Diagram: Unittest Integration Workflow

sequenceDiagram
    participant Pytest as Pytest Collection
    participant UnitTestClass as unittest.TestCase Subclass
    participant UnitTestLoader as unittest.TestLoader
    participant TestMethod as TestCaseFunction Item
    participant FixtureMgr as Pytest Fixture Manager
    participant TestRunner as unittest TestCase Runner

    Pytest->>UnitTestClass: Check if subclass of unittest.TestCase
    UnitTestClass->>UnitTestLoader: Get test method names
    UnitTestLoader-->>Pytest: List of test method names
    Pytest->>TestMethod: Create pytest test items for methods
    Pytest->>FixtureMgr: Register class and method setup/teardown fixtures
    TestMethod->>TestRunner: On runtest(), execute test method
    TestRunner-->>TestMethod: Report test result (success, failure, skip)
    TestMethod->>Pytest: Raise pytest exceptions on failure/skip for reporting

Mermaid Flowchart: Doctest Collection and Execution

flowchart TD
    A[Start Collection] --> B{Is file a .py module?}
    B -- Yes & --doctest-modules --> C[Collect DoctestModule]
    B -- No --> D{Is file a doctest text file?}
    D -- Yes --> E[Collect DoctestTextfile]
    D -- No --> F[Skip file]
    C --> G[Find doctests in module]
    E --> H[Parse doctests from text]
    G --> I[Create DoctestItem for each test]
    H --> I
    I --> J[Run DoctestItem]
    J --> K{Failures?}
    K -- Yes --> L[Report failures with diff]
    K -- No --> M[Test passed]

This documentation explains the integration of unittest and doctest frameworks within pytest, focusing on how tests from these frameworks are discovered, executed, and reported, thereby enabling users to leverage pytest’s capabilities on a wide variety of test formats.