pytest-acereports
Zero-setup HTML reporting for pytest: one self-contained file per run with logs, API traffic, screenshots, retries and flaky-test detection. The same report as Ace Reports for .NET.
Website: https://harshadlambate.github.io/AceReportsWebsite/ · Live demo report: https://harshadlambate.github.io/AceReportsWebsite/demo.html
Setup
Install the package. That's all:
pip install pytest-acereports
The plugin registers itself with pytest. Run your tests as usual and the report is written to
test-results/AceReport_<timestamp>.html in your project's root folder; the path is printed at the
end of the run.
To turn reporting off: pytest --no-acereports, or acereports = false in pytest.ini.
Configuration
Add this hook to a conftest.py. Ace Reports calls it before the first test runs:
from acereports import ace
def pytest_acereports_configure(options):
ace.suite_name("Checkout Regression") # default: the name of the project folder
ace.environment_name("UAT") # see "Environment name" below
ace.dark_theme() # or light_theme() / system_theme() (default)
# ace.output_path("reports/report.html")
# ace.capture_http_traffic(False) # API capture is on by default
Or set the same things in pytest.ini (or pyproject.toml / tox.ini):
[pytest]
acereports_suite_name = Checkout Regression
acereports_environment = UAT
acereports_theme = dark
acereports_output = reports/report.html
acereports_capture_http = true
acereports_capture_logging = true
acereports_readable_names = true
pytest --acereports-output=PATH overrides the output path for one run.
Environment name
Resolved in this order, first match wins:
ace.environment_name("QA")- the
ACEREPORTS_ENVIRONMENTenvironment variable acereports_environmentin pytest.iniLocal
Logging from a test
from acereports import ace
ace.info("Submitting payment")
ace.pass_("Payment authorized") # 'pass' is a Python keyword, hence the underscore
ace.fail("Refund was accepted but should have been rejected") # logs only; use assert to fail
ace.debug("Skipping optional 3-D Secure step")
Each call attaches to whichever test is running. Records from Python's logging module are added to
the test's log as well. pytest's own log_level option decides what gets through, so set
log_level = INFO in pytest.ini to see INFO messages.
Screenshots
A screenshot is taken automatically when a test fails, before fixtures are torn down, so the browser is still open. Take your own at any point; each becomes its own tab in the report:
ace.take_screenshot() # "Screenshot 1", "Screenshot 2", ...
ace.take_screenshot("After login") # named tab
ace.take_screenshot("Cart page", image=png_bytes) # an image you already have
Ace Reports finds the page by itself when the test uses a fixture whose name contains page,
driver or browser, such as pytest-playwright's page, or has such an attribute on its test
class. A browser created inside the test function has to be handed over once:
page = browser.new_page()
ace.use_screenshot_source(page) # Playwright Page, Selenium WebDriver, ...
Works with Playwright (sync API), Selenium, and anything with a screenshot() or
get_screenshot_as_png() method. With Playwright's async API, take the screenshot yourself and pass
it in with image=await page.screenshot().
API traffic
Every HTTP call made with requests or httpx (sync and async) is captured: method, URL,
request and response bodies, status, duration, and connection errors. It is shown per attempt in the
API tab. Authorization, Proxy-Authorization, Cookie and Set-Cookie headers are redacted.
Turn it off with ace.capture_http_traffic(False).
Categories
Markers are categories, from the test, its class and its module:
pytestmark = pytest.mark.checkout # every test in the file
@pytest.mark.smoke
@pytest.mark.category("UAT, Payments") # names that are not valid identifiers
def test_pay():
...
Markers that steer pytest or a plugin (parametrize, skip, xfail, flaky, usefixtures, ...)
are not categories. A test with no category is filed under "Uncategorized".
Retries and flaky tests
Retries come from pytest-rerunfailures:
@pytest.mark.flaky(reruns=3)
def test_checkout():
...
or pytest --reruns 3 for every test. Each attempt keeps its own logs, API calls, error and
screenshots, shown as separate attempt tabs. A test is retried when it took more than one attempt,
and flaky when it ultimately passed after an earlier attempt failed.
What is recorded
| pytest | Report |
|---|---|
| test function / method | one row; test_create_post is shown as "Create post" (set acereports_readable_names = false to keep the function name) |
@pytest.mark.parametrize |
one row per case; parameters listed as name=value |
| class, or module when there is no class | the "Test Group" column |
| markers | category tags (a test can have several) |
| setup or teardown errors | failed, with "Error in setup: ..." / "Error in teardown: ..." |
skip, skipif, xfail |
left out of the table; skipped tests are counted |
@pytest.mark.ace_name("Valid User Login") |
the name shown in the report (also works on pytest.param(..., marks=...)) |
pytest-bdd
Gherkin scenarios run with pytest-bdd are recorded with
their scenario title as the name, their feature as the group, their tags as categories and their
example row as arguments. Each step is a GIVEN / WHEN / THEN / AND / BUT line in the log;
a failing step carries its error, and the steps it prevented are listed as skipped. Nothing to
configure.
Parallel runs
Works with pytest-xdist (pytest -n auto): every worker's
results end up in one report.
Requirements
Python 3.9+ and pytest 7.0+.
License
Ace Reports is free to use under the PolyForm Perimeter License 1.0.1.
Commercial terms (OEM, white-label, or a full buy-out) are available: see the website.
Found it useful? Buy me a coffee ☕
Metadata
Release files for pytest-acereports 1.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pytest_acereports-1.0.1.tar.gz | 42.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pytest_acereports-1.0.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 85.7 kB
Release files / pytest_acereports-1.0.1.tar.gz
| Download URL | pytest_acereports-1.0.1.tar.gz |
|---|---|
| Size | 42.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3b6650c14857fd5da57e5f31aadf75710c58e14d72dc1e0a45a779f131be0c37
|
|
BLAKE2b-256 checksum How to use checksums |
0005c27c921202eb43475573973873abf32d9a4eaf194528303189d1ddf3dcd5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.9
|
Release files / pytest_acereports-1.0.1-py3-none-any.whl
| Download URL | pytest_acereports-1.0.1-py3-none-any.whl |
|---|---|
| Size | 43.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
bc2b5ed9ae9a76a92152cb3ed3630a5efec040fc728a76f2e6a0c8fa470f284b
|
|
BLAKE2b-256 checksum How to use checksums |
c75f5c43204a3848a5ae6a75898e75ca91ec0761787f4ece436e23d4489f57d6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.9
|