Configures ExtentReports v5 for a JVM (or .NET via `extentreports-dotnet`) test run: wires `ExtentSparkReporter`, `attachReporter`, `createTest`, the `info`/`pass`/`warning`/`skip`/`fail` log chain, screenshots via `MediaEntityBuilder`, hierarchical `createNode` parent/child tests, and category/author/device labels, emitting a static HTML report alongside JUnit XML for CI artifact upload. Use when a suite on the Aventstack ExtentReports stack wants a richer per-test HTML narrative than JUnit XML gives; for code-coverage reporting use jacoco-analysis, and for hosted cross-run flakiness analytics use currents-integration.
75
94%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Deep reference for the extentreports SKILL.md. Consult for the richer report API (hierarchical tests, category / author / device labels, exception capture, code blocks) and for wiring the reporter into a JUnit 5 / TestNG run plus CI artifact upload.
Per extent-wiki:
extent.createTest("ParentWithChild")
.createNode("Child")
.pass("This test is created as a toggle as part of a child test of 'ParentWithChild'");The parent appears as a collapsible toggle in the report; children nest underneath. Useful for grouping per-suite tests under a suite-level node, or per-step interactions under a per-test node.
Per extent-wiki:
extent.createTest("Tags").assignCategory("MyTag")
.pass("The test 'Tags' was assigned by the tag MyTag");
extent.createTest("Authors").assignAuthor("TheAuthor")
.pass("This test 'Authors' was assigned by a special kind of author tag.");
extent.createTest("Devices").assignDevice("TheDevice")
.pass("This test 'Devices' was assigned by a special kind of devices tag.");These metadata fields drive the report's filter sidebar - by tag, author, device - making the report navigable when there are hundreds of tests. Use:
git blame).Per extent-wiki:
extent.createTest("Exception")
.fail(new RuntimeException("A runtime exception occurred!"));Passing an exception to .fail(...) captures the message + full
stack trace in the report. Wire this into the test framework's
failure hook so every failed test gets the trace inline.
Per extent-wiki:
extent.createTest("CodeBlock").generateLog(
Status.PASS,
MarkupHelper.createCodeBlock(CODE1, CODE2));MarkupHelper.createCodeBlock(...) produces syntax-highlighted
JSON / SQL / code blocks in the report - useful for capturing the
request body that triggered a failure.
JUnit 5 with a per-test extension:
public class ExtentTestWatcher implements TestWatcher, BeforeAllCallback, AfterAllCallback {
private static ExtentReports extent;
@Override
public void beforeAll(ExtensionContext ctx) {
extent = new ExtentReports();
extent.attachReporter(new ExtentSparkReporter("target/Spark/Spark.html"));
}
@Override
public void testSuccessful(ExtensionContext ctx) {
extent.createTest(ctx.getDisplayName()).pass("OK");
}
@Override
public void testFailed(ExtensionContext ctx, Throwable cause) {
extent.createTest(ctx.getDisplayName()).fail(cause);
}
@Override
public void afterAll(ExtensionContext ctx) {
extent.flush(); // critical
}
}Register via @ExtendWith(ExtentTestWatcher.class) on the test
class.
- run: ./mvnw -B verify
- name: Upload Extent report
if: always()
uses: actions/upload-artifact@v4
with:
name: extent-report
path: target/Spark/
retention-days: 30if: always() is critical - Extent matters most on failure runs.
The HTML is for humans; keep emitting JUnit XML as the machine-readable
CI gate (extent-readme) and surface the Spark HTML alongside it.