{"id":8540,"library":"pytest-reporter","title":"pytest-reporter","description":"pytest-reporter is a Pytest plugin that enables the generation of highly customizable test reports using templates. It provides the data context from a Pytest session, allowing users to create various text-based reports like HTML, LaTeX, or CSV by implementing their own rendering logic. The library is actively maintained with a regular release cadence, often addressing compatibility with new `pytest` versions and enhancing report data.","status":"active","version":"0.5.3","language":"en","source_language":"en","source_url":"https://github.com/christiansandberg/pytest-reporter","tags":["pytest","testing","reporting","plugin","templates","html"],"install":[{"cmd":"pip install pytest-reporter","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Core testing framework that this plugin extends.","package":"pytest","optional":false},{"reason":"For parallel test execution; affects the availability of some report context data (e.g., 'call' information).","package":"pytest-xdist","optional":true},{"reason":"A common template engine used for rendering reports; not strictly required by pytest-reporter but necessary for most custom HTML/text reports.","package":"jinja2","optional":true}],"imports":[{"note":"These are common imports when creating a custom report template using Jinja2 within a conftest.py file.","symbol":"Environment, FileSystemLoader, TemplateNotFound","correct":"from jinja2 import Environment, FileSystemLoader, TemplateNotFound"}],"quickstart":{"code":"# File: conftest.py\nfrom jinja2 import Environment, FileSystemLoader, TemplateNotFound\n\ndef pytest_reporter_render(template_name, dirs, context):\n    \"\"\"This hook is called to render a report template.\"\"\"\n    env = Environment(loader=FileSystemLoader(dirs))\n    try:\n        template = env.get_template(template_name)\n    except TemplateNotFound:\n        # Let other template plugins handle it if not found here\n        return None\n    return template.render(context)\n\n# File: templates/my_report.html\n<!-- Example Jinja2 template -->\n<!DOCTYPE html>\n<html>\n<head><title>Pytest Report</title></head>\n<body>\n    <h1>Test Report</h1>\n    <p>Started: {{ started|strftime('%Y-%m-%d %H:%M:%S') }}</p>\n    <p>Total tests: {{ tests|length }}</p>\n    <ul>\n    {% for test in tests %}\n        <li>{{ test.item.nodeid }} - Status: {{ test.status.word }}\n            {% if test.phases %}\n                <ul>\n                {% for phase in test.phases %}\n                    <li>Phase: {{ phase.name }} - Status: {{ phase.status.word }}</li>\n                {% endfor %}\n                </ul>\n            {% endif %}\n        </li>\n    {% endfor %}\n    </ul>\n</body>\n</html>\n\n# File: test_example.py\ndef test_success():\n    assert True\n\ndef test_failure():\n    assert False\n\n# To run and generate report (from project root):\n# pytest --template-dir=templates --template=my_report.html --report=report.html\n\n","lang":"python","description":"To get started, create a `templates` directory with a Jinja2 HTML template (e.g., `my_report.html`). Then, in your `conftest.py`, implement the `pytest_reporter_render` hook to define how templates are loaded and rendered. Finally, run `pytest` from your project root, specifying the template directory, template file, and output report path using command-line options."},"warnings":[{"fix":"Review and update custom code to remove dependencies on `function_context`. Use other available context objects like `config` or `session.tests`.","message":"The `function_context` fixture was removed in version 0.5.0. Any custom template or plugin relying on this fixture will break.","severity":"breaking","affected_versions":"0.5.0+"},{"fix":"Update any custom plugins or `conftest.py` implementations to use `pytest_warning_recorded` instead.","message":"The internal `pytest_warning_captured` hook was replaced by `pytest_warning_recorded` in version 0.5.0. Plugins implementing the older hook will cease to function correctly.","severity":"breaking","affected_versions":"0.5.0+"},{"fix":"Ensure `jinja2` or your chosen templating engine is installed (`pip install jinja2`) and that `pytest_reporter_render` is correctly implemented in your `conftest.py` to handle template loading and rendering.","message":"The plugin provides data to templates but does not include a rendering engine (like Jinja2) by default. Users must implement the `pytest_reporter_render` hook in `conftest.py` and provide their own template engine integration.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Templates should include checks (e.g., `{% if phase.call %}` in Jinja2) before attempting to access `phase.call` to ensure compatibility with `pytest-xdist`.","message":"When using `pytest-xdist` for parallel execution, the `tests[].phases[].call` item within the template context may be optional or absent for some phases. Accessing it without a check can lead to `KeyError`.","severity":"gotcha","affected_versions":"0.4.0+"},{"fix":"This change primarily affects internal workings. Users experiencing unexpected environment issues post-upgrade should verify their `pytest` and related plugin versions. Ensure compatibility with `pytest`'s own dependency changes.","message":"Version 0.5.3 replaced the use of `pkg_resources`. While this was a fix, environments or custom extensions that implicitly relied on `pytest-reporter`'s previous `pkg_resources` usage might encounter compatibility issues.","severity":"breaking","affected_versions":"0.5.3+"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Verify that the `--template-dir` argument points to the correct directory containing your template, and that the `--template` argument specifies the correct filename within that directory. E.g., `pytest --template-dir=templates --template=my_report.html ...`.","cause":"The template file specified with `--template` was not found in the directories provided by `--template-dir` (or implied by default).","error":"jinja2.exceptions.TemplateNotFound: my_report.html"},{"fix":"Inspect the template and any custom filters or Python code invoked by the template for operations that attempt to hash a dictionary. Ensure that dictionary keys are strings or other hashable types.","cause":"This typically occurs within the template rendering logic (e.g., Jinja2) when attempting to use a dictionary as a key in a set or other context where hashable types are required. This can happen with complex custom template filters or logic manipulating context objects.","error":"TypeError: unhashable type: 'dict'"},{"fix":"Modify the template to conditionally check for the existence of `call` before accessing it, like `{% if phase.call %}{{ phase.call.duration }}{% endif %}`.","cause":"A template attempted to access `test.phases[].call` when `pytest-xdist` was in use, and for that specific phase, the `call` information was not available.","error":"KeyError: 'call' during template rendering"},{"fix":"Ensure `--report=<output_path>` is specified. Confirm your `pytest_reporter_render` hook in `conftest.py` returns the rendered content. Check the template for syntax errors or issues that prevent it from producing output.","cause":"This can happen if the `--report` command-line option is missing, if the `pytest_reporter_render` hook is not implemented correctly, or if the template itself is malformed and fails to render content.","error":"No report generated / Report file is empty"}]}