AceReports.Xunit
1.0.1
dotnet add package AceReports.Xunit --version 1.0.1
NuGet\Install-Package AceReports.Xunit -Version 1.0.1
<PackageReference Include="AceReports.Xunit" Version="1.0.1" />
<PackageVersion Include="AceReports.Xunit" Version="1.0.1" />
<PackageReference Include="AceReports.Xunit" />
paket add AceReports.Xunit --version 1.0.1
#r "nuget: AceReports.Xunit, 1.0.1"
#:package AceReports.Xunit@1.0.1
#addin nuget:?package=AceReports.Xunit&version=1.0.1
#tool nuget:?package=AceReports.Xunit&version=1.0.1
AceReports.Xunit
Zero-setup HTML reporting for xUnit v3: one self-contained file per run with logs, API traffic, screenshots, retries and flaky-test detection.
Setup
Install the package. That's all:
dotnet add package AceReports.Xunit
The package wires itself into the test run during the build, records every test, captures HTTP
traffic, and writes TestResults/AceReport_<timestamp>.html next to your test binaries.
To turn reporting off for a project: <EnableAceReports>false</EnableAceReports>.
Configuration
Add a class implementing IAceReportsStartup anywhere in the test project. Ace Reports finds it and
calls it before the first test runs — no DI container, no attribute, no registration:
using AceReports;
using AceReports.Configuration;
internal sealed class AceReportsStartup : IAceReportsStartup
{
public void Configure(AceReportsConfiguration options)
{
Ace.SuiteName("Smoke Tests"); // default: the test assembly name
Ace.EnvironmentName("UAT"); // see "Environment name" below
Ace.DarkTheme(); // or LightTheme() / SystemTheme() (default)
// Ace.OutputPath(@"C:\ci\out\report.html");
// Ace.CaptureHttpTraffic(false); // API capture is on by default
}
}
xUnit v3 has no
Startup/ConfigureServicesconvention of its own (that belongs to the separateXunit.DependencyInjectionpackage), so a plainConfigureServicesmethod is never called by the runner. Ace Reports also invokes aConfigureServices(IServiceCollection)method if it finds one, so that shape keeps working, butIAceReportsStartupis the reliable hook.
If your project does run a DI container, services.StartAceReports() registers retry detection and
reads the hosting environment name.
Environment name
Resolved in this order, first match wins:
Ace.EnvironmentName("QA")ACEREPORTS_ENVIRONMENTenvironment variable<AceReportsEnvironment>QA</AceReportsEnvironment>in the test project, ordotnet test -p:AceReportsEnvironment=QADOTNET_ENVIRONMENT/ASPNETCORE_ENVIRONMENT- A registered
IHostEnvironment - The build configuration (
Debug,Release, ...)
Logging from a test
Ace.Info("Submitting payment");
Ace.Pass("Payment authorized");
Ace.Fail("Refund was accepted but should have been rejected");
Ace.Debug("Skipping optional 3-D Secure step");
Each call attaches to whichever test is currently running — no instance, no key to pass around.
Screenshots
Screenshots are captured automatically when a test fails. A test can add its own at any point, and each one becomes its own tab under the report's Screenshots tab:
Ace.TakeScreenshot(); // "Screenshot 1", "Screenshot 2", ...
Ace.TakeScreenshot("After login"); // named tab
// Already have the image? Pass it in:
Ace.TakeScreenshot(driver.GetScreenshot().AsByteArray, "Cart page");
Ace Reports finds the page by itself when the page, context or browser is a field or property on the test class (any member whose name contains Page, Browser or Driver) — nothing to write in the test body. When it lives in a local variable inside the test method, hand it over once, since nothing outside that method can reach a local:
var page = await context.NewPageAsync();
Ace.UseScreenshotSource(page); // Playwright IPage, Selenium IWebDriver, Puppeteer IPage, ...
From then on both Ace.TakeScreenshot(...) and the automatic screenshot on failure use it.
If the page or driver is a property/field on the test class, it is detected automatically and this
call is not needed. For anything unusual, register your own provider:
ScreenshotManager.Register(new MyScreenshotProvider()); // implements IScreenshotProvider
It never fails a test: when no screenshot source is available it records a DEBUG log line saying so
and returns false.
API traffic
Every HttpClient request in the test process is captured — method, URL, bodies, status, duration,
and transport exceptions — and shown per attempt in the API tab. Authorization, Cookie and
Set-Cookie headers are redacted. No client-specific code is needed; turn it off with
Ace.CaptureHttpTraffic(false).
Categories
A test can belong to more than one category — either style works, and they combine:
[Trait("Category", "payments")]
[Trait("Category", "smoke")]
[Trait("Category", "payments,smoke")] // comma/semicolon-separated splits too
A multi-category test counts toward every category it carries in the "Results by Category" chart. In the table each category is a coloured tag; clicking a tag (or a bar in the chart) filters the table to that category.
Flaky vs. retried
A test is retried when it took more than one attempt, and flaky when it ultimately passed after an earlier attempt failed. Each attempt keeps its own logs, API traffic, error and screenshots, shown as separate attempt tabs.
License
Ace Reports is source-available under the PolyForm Perimeter License 1.0.1: use it for anything you like, including inside your company, except building a product that competes with Ace Reports.
Commercial terms (OEM, white-label, or a full buy-out) are available — see COMMERCIAL-LICENSE.md.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- AceReports (>= 1.0.1)
- Microsoft.Extensions.Hosting (>= 10.0.12)
- Microsoft.Extensions.Logging (>= 10.0.12)
- xunit.v3.extensibility.core (>= 4.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Fixes an ambiguous IAceReportsStartup reference in AceReports.Xunit: If you referenced AceReports.Xunit.IAceReportsStartup, please change it to AceReports.IAceReportsStartup. Requires xUnit v3 4.0 or later.