unittest.rst

Overview

This documentation file provides guidance on how to use Python's built-in `unittest`-based tests together with the `pytest` testing framework. The file explains how `pytest` can seamlessly run existing `unittest.TestCase` test suites, enabling test runners to leverage `pytest` features without rewriting tests immediately. It covers compatibility aspects, supported and unsupported features, integration of `pytest` fixtures into `unittest` test classes, and best practices for mixing both frameworks.

The document serves as a practical tutorial and reference for developers who want to incrementally migrate or augment `unittest`-based tests with `pytest` capabilities, enhancing test reporting, fixture usage, parallel execution, and debugging.


Detailed Explanation

How pytest runs unittest-based tests

`pytest` natively supports discovering and running tests written as `unittest.TestCase` subclasses. By simply invoking `pytest` on a directory or files containing `unittest` tests, it will:

Unsupported unittest features

Currently, `pytest` does **not** support:

Benefits of running unittest with pytest

Running your existing `unittest` test suite with `pytest` enables several advantages without changing test code:

Supported and unsupported pytest features in unittest.TestCase

Supported pytest features inside `unittest.TestCase` subclasses:

Unsupported pytest features:

Mixing pytest fixtures into unittest.TestCase classes

`pytest` fixtures can be integrated into `unittest.TestCase` tests by using:

Fixtures can be used to set up shared resources, for example, a class-scoped database object:

# conftest.py
import pytest

@pytest.fixture(scope="class")
def db_class(request):
    class DummyDB:
        pass
    request.cls.db = DummyDB()

And used in a `unittest.TestCase` test:

import unittest
import pytest

@pytest.mark.usefixtures("db_class")
class MyTest(unittest.TestCase):
    def test_method1(self):
        assert hasattr(self, "db")
        assert 0, self.db  # fail for demo purposes

    def test_method2(self):
        assert 0, self.db  # fail for demo purposes

This approach allows sharing fixture-provided state as class attributes accessible in test methods.

Using autouse fixtures

Fixtures marked with `autouse=True` are automatically applied to all test methods in the scope they are defined. For example:

import unittest
import pytest

class MyTest(unittest.TestCase):
    @pytest.fixture(autouse=True)
    def initdir(self, tmp_path, monkeypatch):
        monkeypatch.chdir(tmp_path)
        tmp_path.joinpath("samplefile.ini").write_text("# testdata", encoding="utf-8")

    def test_method(self):
        with open("samplefile.ini", encoding="utf-8") as f:
            s = f.read()
        assert "testdata" in s

This fixture runs before each test method, setting up a temporary directory with a sample file.

Important notes


Usage Examples

**Running existing unittest tests via pytest:**

pytest tests

**Using a pytest fixture in a unittest class (class-scoped):**

import pytest
import unittest

@pytest.fixture(scope="class")
def resource(request):
    request.cls.resource = "some resource"

@pytest.mark.usefixtures("resource")
class TestExample(unittest.TestCase):
    def test_resource(self):
        assert self.resource == "some resource"

**Defining an autouse fixture inside a unittest class:**

import pytest
import unittest

class TestAutouse(unittest.TestCase):
    @pytest.fixture(autouse=True)
    def setup_env(self, tmp_path, monkeypatch):
        monkeypatch.chdir(tmp_path)
        tmp_path.joinpath("config.ini").write_text("[settings]", encoding="utf-8")

    def test_config_exists(self):
        with open("config.ini") as f:
            contents = f.read()
        assert "[settings]" in contents

Implementation Details


Interactions with Other Parts of the System


Mermaid Diagram

The following class diagram illustrates the typical structure of a `unittest.TestCase` subclass using pytest fixtures, showing how fixtures relate to the test class and its methods:

classDiagram
    class DummyDB {
        <<fixture resource>>
    }

    class MyTest {
        +db: DummyDB
        +test_method1()
        +test_method2()
    }

    DummyDB <.. MyTest : uses

**Explanation:**

This diagram emphasizes the integration pattern: pytest fixtures provide resources that unittest test classes consume as attributes, allowing `unittest.TestCase` tests to benefit from pytest's fixture system without changing method signatures.


References


This completes the comprehensive technical documentation for the [unittest.rst](/projects/286/67543) file.