pytest-html-plus-action¶

Run pytest with pytest-html-plus and get rich HTML reports, JSON outputs, step summaries, and PR comments — without adding the plugin to your project dependencies.


Overview¶

This GitHub Action installs and runs pytest-html-plus in your CI pipeline. It is designed for teams who want report generation handled entirely by the action, keeping their pyproject.toml or requirements.txt clean.

What it does:

  • Installs pytest-html-plus and runs your test suite

  • Generates an HTML report and uploads it as a workflow artifact

  • Writes a test summary to the GitHub step summary page

  • Optionally posts a summary comment on pull requests

  • Exposes structured step outputs (total, passed, failed, skipped, duration) for downstream steps


Quick Start¶

- uses: reporterplus/pytest-html-plus-action@v1

That’s it. With all defaults, this will:

  • Run pytest from the repo root

  • Generate final_report.json and an HTML report in report_output/

  • Upload the HTML report as a workflow artifact named pytest-html-plus-report

  • Write a summary to the GitHub step summary page


Inputs¶

Input

Description

Default

test_path

Path or target for pytest (e.g. tests/). If empty, pytest discovery runs from repo root.

""

pytest_args

Additional arguments passed directly to pytest.

""

json_report

Path for the JSON report file.

final_report.json

html_output

Directory to save the HTML report.

report_output

screenshots

Directory to save screenshots.

screenshots

`` capture_screenshots``

When to capture screenshots: failed, all, or none.

failed

` should_open_report`

When to auto-open the report locally: always, failed, or never.

failed

generate_xml

Generate a JUnit-style XML report.

false

xml_report

Path for the XML report file.

""

plus_email

Send the HTML report via email (requires email config in plugin).

false

use_poetry

Run pytest through Poetry (`` poetry run pytest``). Cannot be combined with use_uv.

false

use_uv

Run pytest through uv (uv run pytest). Cannot be combined with use_poetry.

false

git_branch

Git branch name to embed in the report.

""

git_commit

Git commit SHA to embed in the report.

""

post_pr_comment

Post a summary comment on the pull request.

false

github_token

GitHub token for posting PR comments. Required when post_pr_comment is true.

""

u pload_html_artifact

Upload the HTML report as a GitHub Actions artifact.

true

` html_artifact_name`

Name of the uploaded artifact.

pyte st-html-plus-report

plugin_version

Version of pytest-html-plus to install. Defaults to latest.

""

Outputs¶

Output

Description

total

Total number of tests

passed

Number of passed tests

failed

Number of failed or errored tests

skipped

Number of skipped tests

duration

Sum of all test durations in seconds


Use Cases¶

1. Minimal — zero config¶

Run pytest with full report generation and artifact upload, no configuration needed.

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: "3.12"
      - run: pip install -r requirements.txt
      - uses: reporterplus/pytest-html-plus-action@v1

2. Run a specific test directory¶

- uses: reporterplus/pytest-html-plus-action@v1
  with:
    test_path: tests/unit

3. Pass additional pytest arguments¶

Coverage, reruns, markers, and any other pytest flags go in pytest_args.

- uses: reporterplus/pytest-html-plus-action@v1
  with:
    test_path: tests/
    pytest_args: >-
      --cov=mypackage
      --cov-fail-under=80
      --cov-report=term
      --reruns 2
      --ignore=tests/browser

4. Poetry project¶

- uses: reporterplus/pytest-html-plus-action@v1
  with:
    use_poetry: "true"
    test_path: tests/

Make sure poetry install has already run in a previous step.


5. uv project¶

uv is not pre-installed on GitHub-hosted runners, so install it first with the official setup action.

- uses: astral-sh/setup-uv@v5

- name: Install dependencies
  run: uv sync

- uses: reporterplus/pytest-html-plus-action@v1
  with:
    use_uv: "true"
    test_path: tests/

use_uv and use_poetry are mutually exclusive — setting both to true will fail the step with a clear error before pytest runs.


6. Post a summary comment on pull requests¶

- uses: reporterplus/pytest-html-plus-action@v1
  with:
    post_pr_comment: "true"
    github_token: ${{ secrets.GITHUB_TOKEN }}

The comment includes total, passed, failed, skipped, duration, and a list of up to 5 failed test cases.

Security note: Always use secrets.GITHUB_TOKEN rather than a personal access token — it is automatically scoped to the current repository and expires after the run. The token only needs issues: write permission. If your repo accepts PRs from forks, review your workflow’s trigger settings before enabling post_pr_comment, as fork workflows may have access to the token depending on your repository configuration.


7. Embed git context in the report¶

Useful when sharing reports outside of GitHub — the report itself shows which branch and commit it was generated from.

- uses: reporterplus/pytest-html-plus-action@v1
  with:
    git_branch: ${{ github.ref_name }}
    git_commit: ${{ github.sha }}

8. Generate a JUnit XML report alongside HTML¶

Useful for integrating with tools that consume JUnit XML (e.g. test analytics platforms, SonarQube).

- uses: reporterplus/pytest-html-plus-action@v1
  with:
    generate_xml: "true"
    xml_report: reports/junit.xml

9. Use step outputs to conditionally fail or notify¶

- uses: reporterplus/pytest-html-plus-action@v1
  id: pytest
  with:
    test_path: tests/

- name: Print test summary
  run: |
    echo "Total: ${{ steps.pytest.outputs.total }}"
    echo "Passed: ${{ steps.pytest.outputs.passed }}"
    echo "Failed: ${{ steps.pytest.outputs.failed }}"

- name: Notify on failure
  if: ${{ steps.pytest.outputs.failed > 0 }}
  run: echo "::warning::${{ steps.pytest.outputs.failed }} test(s) failed"

10. Pin the plugin version for reproducible CI¶

- uses: reporterplus/pytest-html-plus-action@v1
  with:
    plugin_version: "1.2.0"

Recommended for teams with strict dependency policies or those who want to upgrade the plugin intentionally rather than automatically picking up the latest release.


11. Custom artifact name per matrix leg¶

When running a test matrix (e.g. multiple OS or Python versions), give each artifact a unique name so they don’t overwrite each other.

jobs:
  test:
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest]
        python-version: ["3.11", "3.12"]
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python-version }}
      - run: pip install -r requirements.txt
      - uses: reporterplus/pytest-html-plus-action@v1
        with:
          html_artifact_name: report-${{ matrix.os }}-py${{ matrix.python-version }}

12. Screenshot capture on failure (browser/UI tests)¶

For projects using Playwright or Selenium, screenshots of failed tests are captured automatically and included in the HTML report.

- uses: reporterplus/pytest-html-plus-action@v1
  with:
    test_path: tests/browser
    capture_screenshots: failed
    screenshots: test-screenshots

Set capture_screenshots: all to capture every test regardless of outcome.


13. PYTHONWARNINGS — treat warnings as errors¶

The action has no dedicated input for environment variables, but any variable written to $GITHUB_ENV in a prior step persists into the action’s environment.

- name: Configure Python warnings
  run: echo "PYTHONWARNINGS=error" >> $GITHUB_ENV

- uses: reporterplus/pytest-html-plus-action@v1
  with:
    test_path: tests/
    xml_report: reports/junit_warnings.xml
    html_output: report_output_warnings

14. Full production setup¶

A complete example combining git context, PR comments, XML output, coverage, and reruns.

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-python@v5
        with:
          python-version: "3.12"

      - name: Install dependencies
        run: pip install -r requirements.txt

      - uses: reporterplus/pytest-html-plus-action@v1
        id: pytest
        with:
          use_poetry: "false"
          test_path: tests/
          pytest_args: >-
            --cov=mypackage
            --cov-fail-under=75
            --cov-report=term
            --reruns 1
          git_branch: ${{ github.ref_name }}
          git_commit: ${{ github.sha }}
          generate_xml: "true"
          xml_report: reports/junit.xml
          html_output: report_output
          html_artifact_name: test-report-${{ github.run_id }}
          post_pr_comment: "true"
          github_token: ${{ secrets.GITHUB_TOKEN }}

      - name: Fail with context if tests failed
        if: ${{ steps.pytest.outputs.failed > 0 }}
        run: |
          echo "${{ steps.pytest.outputs.failed }} of ${{ steps.pytest.outputs.total }} tests failed"
          exit 1

Notes¶

Windows runners: The action uses a bash entrypoint and is not compatible with Windows runners. Use ubuntu-latest or macos-latest.

Self-hosted runners: Ensure Python and pip are available on the runner. The action installs pytest-html-plus at runtime via pip.

Air-gapped environments: If your runner cannot reach PyPI, pre-install pytest-html-plus in your runner image and set plugin_version to the pre-installed version to avoid the install step attempting to upgrade.

PR comments accumulate: Each push to a PR branch posts a new comment rather than updating the previous one. If comment volume is a concern, delete previous bot comments in a prior step using the GitHub API.

uv runners: uv is not pre-installed on GitHub-hosted runners. Add astral-sh/setup-uv@v5 and uv sync as steps before the action. use_uv and use_poetry cannot both be true — the action will exit with an error before pytest runs if both are set.

Rerun compatibility: pytest-rerunfailures works transparently — the JSON report and step outputs reflect the final state after all retries have been exhausted.


License¶

MIT