pytest-acereports
Zero-setup HTML reporting for pytest. Automatically captures every API request and response, flaky tests, takes a screenshot when a test fails, and tracks logs, tracks retries, all in one self-contained HTML file per run.
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
TestResults/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().
Automatic API capture
No code needed: every HTTP call made with requests or httpx (sync and async) is captured
automatically: 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.2
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.2.tar.gz | 43.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pytest_acereports-1.0.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 86.8 kB
Release files / pytest_acereports-1.0.2.tar.gz
| Download URL | pytest_acereports-1.0.2.tar.gz |
|---|---|
| Size | 43.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
198208d5656b1cd0c8103a79b8312e4251e89ba45133335e91ee227509dc1b14
|
|
BLAKE2b-256 checksum How to use checksums |
bcbd654095c147f76c941582eb087be0ccf8d20d192def249c7cb02ffdd039c2
|
| 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.2-py3-none-any.whl
| Download URL | pytest_acereports-1.0.2-py3-none-any.whl |
|---|---|
| Size | 43.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9abb2e62dd1e2329bc09ca84c03b02c4febd54b32a886d12e7b9c76800269502
|
|
BLAKE2b-256 checksum How to use checksums |
37644a83df4041af80e052a2ea114f72cc257081a46031f4ceca0842ff5a9ba9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.9
|