Skip to main content

Release Notes Downloads GitHub CI Status License: MIT

Reusable pytest Plugin Utilities

Building pytest plugins means dealing with the same problems repeatedly: managing configuration options with proper precedence (CLI vs INI vs defaults), creating per-test artifact directories, and sanitizing test names for filesystem paths. This package extracts those common patterns into reusable utilities.

I created this after extracting the config and path handling logic from pytest-playwright-artifacts. Rather than reinvent option handling in every plugin, you can use these utilities to get consistent behavior across pytest plugins.

Installation

uv add pytest-plugin-utils

Usage

Configuration Options

Register pytest options with automatic precedence handling (runtime > CLI > INI > defaults) and type inference.

For Plugin Authors

from pytest_plugin_utils import set_pytest_option, register_pytest_options, get_pytest_option

def pytest_addoption(parser):
    # Define your options (use __package__ for namespace)
    set_pytest_option(
        __package__,
        "api_url",
        default="http://localhost:3000",
        help="API base URL",
        available="all",  # Expose via CLI and INI
        type_hint=str,
    )

    # Register them with pytest
    register_pytest_options(__package__, parser)

def pytest_configure(config):
    # Retrieve with automatic type casting
    api_url = get_pytest_option(__package__, config, "api_url", type_hint=str)

namespace is only used internally by this library to scope its option registry. It does not prefix pytest's CLI flags, config.option attributes, or INI keys. If you register "api_url", the runtime override is config.option.api_url, not a namespaced variant like config.option.my_plugin_api_url.

The available Parameter

The available argument in set_pytest_option controls how the option is exposed to the user:

Value Exposure Description
"all" CLI & INI Adds a --flag and an INI entry.
"cli_option" CLI Only Adds a --flag but no INI entry.
"ini" INI Only Adds an INI entry but no CLI flag.
None Runtime Only Purely programmatic. No CLI or INI exposure.

Advanced: Handling Complex Types (Dictionaries)

For rich data structures like dictionaries that are difficult to express as strings on the command line, use available=None. This allows you to pass Python objects directly via hooks.

Plugin Author:

set_pytest_option(
    __package__,
    "playwright_kwargs",
    default={},
    available=None,  # Runtime only
    type_hint=dict,
)

Plugin User (in conftest.py):

def pytest_configure(config):
    # Set the dictionary directly on the raw option name
    config.option.playwright_kwargs = {
        "timeout": 5000,
        "full_page": True,
        "clip": {"x": 0, "y": 0, "width": 800, "height": 600}
    }

For Plugin Users

Once a plugin has registered options using this package, users can configure them in three ways (in order of precedence):

  1. Command Line (highest priority):

    pytest --api-url=https://prod.example.com
    
  2. INI Configuration (medium priority):

    In pytest.ini:

    [pytest]
    api_url = https://staging.example.com
    

    Or in pyproject.toml:

    [tool.pytest.ini_options]
    api_url = "https://staging.example.com"
    
  3. Runtime/Programmatic (via conftest.py):

    def pytest_configure(config):
        # Override at runtime using the raw option name
        config.option.api_url = "https://custom.example.com"
    

    namespace does not change the attribute name here. For example, get_pytest_option(__package__, config, "api_url") reads from config.option.api_url.

The value resolution follows this precedence chain, with each level overriding the next: Runtime > CLI > INI > Default.

Artifact Directory Management

Create per-test artifact directories with sanitized names:

from pytest_plugin_utils import set_artifact_dir_option, get_artifact_dir

def pytest_configure(config):
    # Configure which option name to use (use __package__ for namespace)
    set_artifact_dir_option(__package__, "my_plugin_output")

def pytest_runtest_setup(item):
    # Get a clean directory for this specific test
    artifact_dir = get_artifact_dir(__package__, item)
    # Returns: /output/test-file-py-test-name-param/

Features

  • Centralized option registry with runtime, CLI, and INI support
  • Automatic INI type inference from Python type hints (bool, str, list[str], list[Path])
  • Smart value casting with fallback precedence handling
  • Filesystem-safe test name sanitization for artifact paths
  • Per-test artifact directory creation and resolution
  • Type-safe configuration retrieval with warnings on mismatches

Related Projects

MIT License


This project was created from iloveitaly/python-package-template

Metadata

Release files for pytest-plugin-utils 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pytest-plugin-utils 0.4.0
File Size Uploaded Provenance
pytest_plugin_utils-0.4.0.tar.gz 8.2 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for pytest-plugin-utils 0.4.0
File Interpreter ABI Platform
pytest_plugin_utils-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 17.5 kB

Release files / pytest_plugin_utils-0.4.0.tar.gz

Download URL pytest_plugin_utils-0.4.0.tar.gz
Size 8.2 kB
Tags Source
SHA-256 checksum
How to use checksums
d40e100d88ae15599ed67780531e502a159e23c3484795bbf4e45c0468520cc4
BLAKE2b-256 checksum
How to use checksums
7ddac91592e11f2837a12d4696b4004d15dc67502e44163cd9478a961386eb77
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.1 {"installer":{"name":"uv","version":"0.11.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / pytest_plugin_utils-0.4.0-py3-none-any.whl

Download URL pytest_plugin_utils-0.4.0-py3-none-any.whl
Size 9.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
06c786c7bbaaabad6ad1d513d731511f3feb829514ec0978be41a43351de5017
BLAKE2b-256 checksum
How to use checksums
7eaa282377aa29a1eb83dd3e39433b29eabdba295ce9b8ae7f2332b1d6b64f63
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.1 {"installer":{"name":"uv","version":"0.11.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for pytest-plugin-utils 0.4.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page