capture-warnings.rst

Overview

This file provides comprehensive documentation on how to capture, control, and assert Python warnings during test execution using the pytest testing framework. It explains pytest's built-in support for warning capture starting from version 3.1, describes mechanisms to filter and handle warnings, and demonstrates how to write tests that assert the presence or absence of warnings. The document also covers configuration options, usage of pytest marks for warnings, and advanced use cases such as recording warnings and customizing failure messages.

This documentation is intended for developers writing tests with pytest who want to manage warning output effectively and ensure that their code emits or suppresses warnings as expected.

Detailed Explanations

Capturing Warnings Automatically

Controlling Warnings

pytest provides a `-W` command-line option (similar to Python's own `-W` flag) to control how warnings are handled during tests:

@pytest.mark.filterwarnings

Disabling Warning Capture

Handling DeprecationWarnings

Asserting Warnings with pytest.warns

Recording Warnings with recwarn Fixture

Additional Use Cases for Warnings in Tests

Custom Failure Messages

Internal pytest Warnings

Resource Warnings and tracemalloc

Important Implementation Details

Interactions with Other Parts of the System

Visual Diagram

The following Mermaid class diagram illustrates the key concepts and entities related to warnings in pytest as documented here, focusing on the main interfaces and interactions for capturing and asserting warnings.

classDiagram
    class pytest {
        +warns(expected_warning, func=None, *args, **kwargs)
        +deprecated_call()
        +mark.filterwarnings(filter_str)
    }

    class WarningsRecorder {
        +__len__()
        +__getitem__(index)
        +__iter__()
        +pop(warning_category)
    }

    class recwarn {
        +__len__()
        +pop(warning_category)
        +__iter__()
    }

    class warnings {
        +warn(message, category)
        +simplefilter(action)
        +catch_warnings()
    }

    pytest ..> WarningsRecorder : returns instance
    pytest ..> recwarn : fixture instance
    WarningsRecorder <.. recwarn : similar interface
    pytest --> warnings : uses internally
    recwarn --> warnings : records warnings
    pytest.warns "context manager" --> WarningsRecorder : captures warnings

Usage Examples

Basic warning capture with pytest

import warnings

def api_v1():
    warnings.warn(UserWarning("api v1 deprecated"))
    return 1

def test_api():
    assert api_v1() == 1

Treat warnings as errors via CLI

pytest -W error::UserWarning test_module.py

Using @pytest.mark.filterwarnings to ignore warnings on a test

import pytest
import warnings

def api_v1():
    warnings.warn(UserWarning("deprecated API"))
    return 1

@pytest.mark.filterwarnings("ignore:deprecated API")
def test_api():
    assert api_v1() == 1

Asserting warning raised with pytest.warns

import warnings
import pytest

def test_warn():
    with pytest.warns(UserWarning, match="my warning"):
        warnings.warn("my warning", UserWarning)

Recording warnings with recwarn fixture

def test_recwarn(recwarn):
    import warnings
    warnings.warn("hello", UserWarning)
    w = recwarn.pop(UserWarning)
    assert "hello" in str(w.message)

Summary

This documentation file extensively covers how pytest captures, filters, controls, and asserts warnings during test runs. It provides both usage instructions and configuration guidance, enabling users to write robust tests that handle warnings appropriately. The interactions with Python's native warnings system, pytest's configuration, and decorators/fixtures are clearly explained, making this a valuable resource for pytest users concerned with warning management.


*End of documentation for `capture-warnings.rst`*