pytest-metadata

raw JSON →
3.1.1 verified Tue May 12 auth: no python install: verified

pytest-metadata is a plugin for pytest that provides access to test session metadata. It collects system information, environment variables (especially from CI systems), and allows users to inject custom data. Currently at version 3.1.1, it is actively maintained by the pytest-dev team, with releases typically aligning with pytest compatibility and new feature additions.

pip install pytest-metadata
error ModuleNotFoundError: No module named 'pytest_metadata'
cause `pytest-metadata` is a pytest plugin that is automatically loaded by pytest when installed; it is not intended for direct module import in test files.
fix
Remove any import pytest_metadata statements from your code. The plugin's functionality is accessed through pytest fixtures (like request) or hooks.
error AttributeError: 'Session' object has no attribute 'pytest_metadata'
cause This error occurs when the `pytest-metadata` plugin is not installed or not correctly loaded by pytest, preventing the `pytest_metadata` attribute from being added to the pytest `session` object.
fix
Ensure the pytest-metadata plugin is installed in your environment using pip install pytest-metadata. Verify your pytest setup allows plugin discovery (e.g., it's not disabled in pytest.ini).
error TypeError: Object of type X is not JSON serializable
cause You are attempting to add data to `pytest_metadata` that is not JSON-serializable (e.g., custom objects, functions, sets, complex types), which causes an error when the plugin tries to serialize the metadata for reports.
fix
Ensure all custom data added to pytest_metadata consists of JSON-compatible types (strings, numbers, booleans, lists, dictionaries). Convert complex objects to their serializable representations (e.g., str(), repr(), or a dictionary representation) before adding them.
breaking Version 2.0.0 of `pytest-metadata` dropped support for Python 2.7 and 3.6. Users on these Python versions must pin to `pytest-metadata < 2.0.0`.
fix Upgrade to Python 3.8+ or use an older version of `pytest-metadata` (e.g., `pip install 'pytest-metadata<2.0.0'`).
breaking Version 3.0.0 grouped CLI options. Existing automation scripts or commands that relied on specific, ungrouped command-line metadata options might need to be updated.
fix Review the `pytest --help` output for the new grouped CLI options and update scripts accordingly. For example, `--metadata KEY VALUE` and `--metadata-from-json-file PATH`.
gotcha When modifying session metadata within a `pytest_configure` hook, directly assigning to `config._metadata['key']` can lead to `AttributeError` if the underlying `_metadata` object is not a dictionary. The robust way to interact with `pytest-metadata`'s internal dictionary is via `config.stash[metadata_key]`.
fix Use `from pytest_metadata.plugin import metadata_key` and access/modify metadata using `config.stash[metadata_key]['your_key'] = 'your_value'` in your `pytest_configure` hook.
gotcha When running tests with `tox` in a Continuous Integration (CI) environment, environment variables (like `CI` or `BUILD_NUMBER` which `pytest-metadata` uses for auto-detection) must be explicitly passed down from the CI runner to the `tox` environment.
fix Configure your `tox.ini` to pass through relevant CI environment variables using the `passenv` directive, e.g., `[testenv] passenv = CI BUILD_NUMBER` etc.
gotcha Metadata is only displayed in the console report header when `pytest` is run with the `--verbose` (`-v`) flag. Without it, the metadata will still be collected and available programmatically or in reports generated by other plugins (e.g., `pytest-html`), but not shown in the standard terminal output.
fix Always include `-v` or `--verbose` in your `pytest` command if you expect to see the collected metadata in the terminal report.
python os / libc status wheel install import disk
3.10 alpine (musl) wheel - 0.45s 30.7M
3.10 alpine (musl) - - 0.45s 30.6M
3.10 slim (glibc) wheel 2.7s 0.31s 31M
3.10 slim (glibc) - - 0.29s 31M
3.11 alpine (musl) wheel - 0.57s 33.7M
3.11 alpine (musl) - - 0.62s 33.4M
3.11 slim (glibc) wheel 2.5s 0.51s 34M
3.11 slim (glibc) - - 0.47s 34M
3.12 alpine (musl) wheel - 0.53s 25.3M
3.12 alpine (musl) - - 0.56s 25.1M
3.12 slim (glibc) wheel 2.5s 0.51s 26M
3.12 slim (glibc) - - 0.51s 26M
3.13 alpine (musl) wheel - 0.47s 25.1M
3.13 alpine (musl) - - 0.48s 24.7M
3.13 slim (glibc) wheel 2.6s 0.47s 26M
3.13 slim (glibc) - - 0.45s 25M
3.9 alpine (musl) wheel - 0.37s 30.1M
3.9 alpine (musl) - - 0.39s 29.9M
3.9 slim (glibc) wheel 3.1s 0.33s 31M
3.9 slim (glibc) - - 0.32s 30M

This quickstart demonstrates how to add custom metadata using a `pytest_configure` hook in `conftest.py`, how to modify the final metadata using the `pytest_metadata` hook, and how to access the collected metadata within a test function via the `metadata` fixture. It also shows how to add metadata via command-line arguments.

import pytest
import os
from pytest_metadata.plugin import metadata_key

# conftest.py (or a pytest plugin)
@pytest.hookimpl(tryfirst=True)
def pytest_configure(config):
    # Initialize metadata_key if not already present (e.g., if pytest-html isn't loaded)
    if not hasattr(config.stash, metadata_key):
        config.stash[metadata_key] = {}

    # Add custom metadata before tests run
    config.stash[metadata_key]["project_name"] = "My Awesome Project"
    config.stash[metadata_key]["run_by_user"] = os.environ.get("USER", "unknown")

@pytest.hookimpl(optionalhook=True)
def pytest_metadata(metadata):
    # This hook modifies the final metadata dictionary that will be reported.
    # For example, remove 'Packages' to simplify the report.
    metadata.pop("Packages", None)
    metadata["custom_value_from_hook"] = "Hello from pytest_metadata hook!"

# test_example.py
def test_access_session_metadata(metadata):
    # The 'metadata' fixture provides access to the collected session metadata
    print(f"\n--- Test-specific Metadata ---")
    print(f"Project Name: {metadata.get('project_name')}")
    print(f"Run By User: {metadata.get('run_by_user')}")
    print(f"Python Version: {metadata.get('Python')}")
    print(f"Custom Value: {metadata.get('custom_value_from_hook')}")

    assert "project_name" in metadata
    assert metadata["project_name"] == "My Awesome Project"
    assert "Python" in metadata
    assert "custom_value_from_hook" in metadata

# To run this example:
# 1. Save the conftest.py and test_example.py files in the same directory.
# 2. Run from your terminal: 
#    pytest -v --metadata cli_key cli_value --metadata another_key another_value
# Expected output will include metadata in the header (due to -v) and in the test print statements.