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):
-
Command Line (highest priority):
pytest --api-url=https://prod.example.com
-
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"
-
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"
namespacedoes not change the attribute name here. For example,get_pytest_option(__package__, config, "api_url")reads fromconfig.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
- pytest-playwright-visual-snapshot: Easy pytest visual regression testing using playwright.
- pytest-line-runner: Run pytest tests by line number instead of exact test name.
- pytest-celery-utils: Pytest plugin for inspecting Celery task queues in Redis during tests.
- pytest-playwright-artifacts: Pytest plugin that captures HTML, screenshots, and console logs on Playwright test failures.
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)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| pytest_plugin_utils-0.4.0.tar.gz | 8.2 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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.