Getting Started

Since the main activity of any devops team is around building and refining application code & tests, reporting generally becomes an afterthought. But, with the Extent framework, it doesn't have to be. Extent Reporting Framework is widely adopted and used in many test frameworks. With its API-style usage, and a wealth of available adapters, listeners and examples, you can get started with beautiful and incredibly descriptive reports in no time.


Community vs Pro Editions

Unlike version 3, there are no differences in the underlying ExtentReports API - both community and professional users enjoy a full-featured API, with the exception of a few reporters. To see which reporters are available in your edition, visit this page. In this documentation website, reporters available only to the professional edition only are marked pro


Migrating from Version 3

If you are migrating from version 3, please note that the core usage remains the same. See the list of breaking changes here.


Download

Extent Core is a required dependency for all formatters or reporters.

Maven
<dependency>
    <groupId>com.aventstack</groupId>
    <artifactId>extentreports</artifactId>
    <version>${version}</version>
</dependency>
Gradle
dependencies {
    compile "com.aventstack:extentreports:${version}"
}
GitHub

extentreports


Javadoc

Javadoc here.


Reporters

Extent allows creation of tests, nodes, events and assignment of tags, devices, authors, environment values etc. This information can be printed to multiple destinations. In our context, a reporter defines the destination.

You can use one or more reporters to create different types of reports. reporters are available for BDD, non-BDD and both - choose one of the reporters from the navigation menu at the top of this page to learn more.

  • ExtentAventReporter pro
  • ExtentBDDReporter pro
  • ExtentCardsReporter pro
  • ExtentEmailReporter pro
  • ExtentHtmlReporter (version-3)
  • ExtentKlovReporter
  • ExtentLoggerReporter
  • ExtentTabularReporter pro

Usage

This section focuses upon the core usage of the framework. Extent framework follows the Observer pattern and each reporter attached becomes an observer and notified of any changes such as creation of a test, assignment of a category to the test, adding an event etc.


Attaching Reporters

To enable or start a reporter, use attachReporter:

ExtentReports extent = new ExtentReports();
extent.attachReporter(reporterType);

A real world example attaching 2 reporters (:

ExtentAventReporter avent = new ExtentAventReporter("/user/build/");
ExtentKlovReporter klov = new ExtentKlovReporter("project", "build");

ExtentReports extent = new ExtentReports();
extent.attachReporter(avent);
extent.attachReporter(klov);

// or:
extent.attachReporter(avent, klov);

Flush

Calling the flush method writes/updates the test information of your reporter to the destination type.

  • ExtentAventReporter: Builds multiple linked output files in HTML format
  • ExtentBDDReporter: Builds multiple linked output files in HTML format
  • ExtentCardsReporter: Builds multiple linked output files in HTML format
  • ExtentEmailReporter: Builds an emailable HTML file
  • ExtentHtmlReporter (version-3): Builds a single HTML file with multiple views (SPA)
  • ExtentKlovReporter: Updates MongoDb upon invocation of each TestListener event
  • ExtentLoggerReporter: Builds multiple linked output files in HTML format
  • ExtentTabularReporter: Builds multiple linked output files in HTML format

Creating Tests

To create tests, use createTest. This method returns a ExtentTest object.

ExtentTest test = extent.createTest("MyFirstTest");
test.pass("details");

// short-hand
extent.createTest("MyFirstTest").pass("details");
	
// description
extent.createTest("MyFirstTest", "Test Description").pass("details");

Creating Nodes

To create nodes, use createNode. This method returns a ExtentTest object.

ExtentReports creates a test (createTest) and ExtentTest creates a node (createNode).

ExtentTest test = extent.createTest("Test"); // level = 0
ExtentTest node = test.createNode("Node");  // level = 1
node.pass("details");

// short-hand
extent.createTest("MyFirstTest").createNode("MyFirstChildTest").pass("details");

// description
ExtentTest node = test.createNode("MyFirstChildTest", "Node Description");

Each test or node created is assigned a level in the test hierarchy. The top-most test has a level value of 0, and level is incremented each time a new step in the hierarchy is achieved.

test (level 0)
  • child (level 1)
    • grandchild (level 2)

A BDD example

Feature (level 0)
  • Scenario (level 1)
    • Given (level 2)
    • When (level 2)
    • Then (level 2)

Creating BDD Tests

To create gherkin-style tests, use the gherkin classes or model names. The example below shows creation of such tests directly using gherkin classes:

// feature
ExtentTest feature = extent.createTest(Feature.class, "Refund item");

// scenario
ExtentTest scenario = feature.createNode(Scenario.class, "Jeff returns a faulty microwave");

// steps
scenario.createNode(Given.class, "Jeff has bought a microwave for $100").pass("pass");
scenario.createNode(And.class, "he has a receipt").pass("pass");
scenario.createNode(When.class, "he returns the microwave").pass("pass");
scenario.createNode(Then.class, "Jeff should be refunded $100").fail("fail");

You can also pass the gherkin keyword directly when creating tests using the GherkinKeyword instance.

// feature
ExtentTest feature = extent.createTest(new GherkinKeyword("Feature"), "Refund item");

// scenario
ExtentTest scenario = feature.createNode(new GherkinKeyword("Scenario"), "Jeff returns a faulty microwave");

// steps
scenario.createNode(new GherkinKeyword("Given"), "Jeff has bought a microwave for $100").pass("pass");
scenario.createNode(new GherkinKeyword("And"), "he has a receipt").pass("pass");
scenario.createNode(new GherkinKeyword("When"), "he returns the microwave").pass("pass");
scenario.createNode(new GherkinKeyword("Then"), "Jeff should be refunded $100").fail("fail");

A ClassNotFoundException is thrown if the supplied keyword is not found.

// Typo, FFeature instead of Feature
// ClassNotFoundException
ExtentTest feature = extent.createTest(new GherkinKeyword("FFeature"), "Refund item");

Selecting a Gherkin Dialect

If you are using a dialect other than the default en or English keywords, you can now specify a gherkin dialect. The API uses the same source for dialects as defined in the gherkin spec. To specify your dialect, simply add this before starting to create tests:

// German
extent.setGherkinDialect("de");

// Norwegian
extent.setGherkinDialect("no");

Removing Tests

Use removeTest to remove a test which was created using createTest or createNode.

ExtentTest test = extent.createTest("Test").fail("reason");
extent.removeTest(test);
ExtentTest test = extent.createTest("Test");
ExtentTest node = test.createNode("Node").fail("reason");
extent.removeTest(node);

Log Events

To create an event for a test or node, use test.log(Status.PASS, "details") or test.pass("details"). The below status are available but the most commonly used are Pass, Fail and Skip.

  • FATAL
  • FAIL
  • ERROR
  • WARNING
  • SKIP
  • PASS
  • INFO
  • DEBUG
ExtentTest test = extent.createTest("TestName");

test.log(Status.PASS, "pass");
test.pass("pass");

test.log(Status.FAIL, "fail");
test.fail("fail");

A test will never be marked with Info and Debug status. These are only available to indicate the type of log, and a test with only these status will be marked as Pass. Fatal has the highest level in the hierarchy and the lowest possible (and default) status in the hierarchy is Pass.

pass < skip < warning < error < fail < fatal

Logging Exceptions

Exceptions can be passed directly when logging events.

Exception e;
test.fail(e);

To enable the Defects tab in some reporters, use this approach to log exceptions instead of passing a string representing the exception.


Assign Tags

You can assign tags or categories to tests using assignCategory.

test.assignCategory("tag");
test.assignCategory("tag-1", "tag-2", ..);

// usage
extent.createTest("Test").assignCategory("tag-1").pass("details");

Assigning tags enables the Tag view in BasicFileReporter reporters.


Assign Devices

You can assign devices to tests using assignDevice.

test.assignDevice("device-name");
test.assignDevice("device-1", "device-2", ..);

// usage
extent.createTest("Test").assignDevice("device-name").pass("details");

Assign Authors

You can assign categories to tests using assignAuthor.

test.assignAuthor("author");
test.assignAuthor("author-1", "author-2", ..);

// usage
extent.createTest("MyFirstTest").assignAuthor("aventstack").pass("details");

Screenshots

You can add file and base64 snapshots to your tests. Both methods are described in this section.

Screenshots - Tests

To add screenshots to tests, use addScreenCaptureFromPath.

Note: This method does not "attach" or "affix" the screenshot the file-based (BasicFileReporter) formatters/reporters, such as the Avent, HTML, Email, Logger etc. Instead, the image is saved on disk and is referenced in the report using the <img> tag.

test.fail("details").addScreenCaptureFromPath("screenshot.png");

Screenshots - Logs

Adding a screenshot to a log is a little different as logs do not accept image paths directly. The path must be provided using MediaEntityBuilder.

MediaModelProvider mediaModel = 
	MediaEntityBuilder.createScreenCaptureFromPath("screenshot.png").build();
test.fail("details", mediaModel);

// or:
test.fail("details", 
	MediaEntityBuilder.createScreenCaptureFromPath("screenshot.png").build());

Screenshots

Base64 Screenshots - Tests

To add base64 screenshots to tests, use addScreenCaptureFromBase64String.

test.addScreenCaptureFromBase64String("base64String");

Base64 Screenshots - Logs

To add base64 screenshots to logs, use createScreenCaptureFromBase64String.

test.fail("details", 
	MediaEntityBuilder.createScreenCaptureFromBase64String("base64String").build());

test.log(Status.FAIL, "details", 
	MediaEntityBuilder.createScreenCaptureFromBase64String("base64String").build());

Inserting HTML

Simply insert custom HTML in the logs by using an HTML tag:

extent.log(LogStatus.INFO, "HTML", "Usage: <b>BOLD TEXT</b>");

Adding System Info

It is possible to add system or environment info for your using using the setSystemInfo method. This automatically adds system information to all started reporters.

extent.setSystemInfo("os", "win7");

Creating system info also enables the System or Environment view in some reporters.


Configuration

The core Extent API supports several configuration options as detailed in this section.


Analysis Strategy

Avent support configuring the analysis strategy by selecting one of the 3 available strategies:

  • AnalysisStrategy.TEST (default)
  • AnalysisStrategy.CLASS
  • AnalysisStrategy.SUITE
  • AnalysisStrategy.BDD

AnalysisStrategy.TEST

Generates stats based on maximum 2 levels - Tests and Steps (children). If none of the Tests in the run-session do not contain any Steps, stats will be based on 1 level only. In the examples below, AnalysisStrategy is not explicitly set since TEST is the default strategy. To explicitly set the strategy use:

extent.setAnalysisStrategy(AnalysisStrategy.TEST);

If there are multiple levels, the bottom-most or the leaf test will be considered as Step. See example-3 for more information.

Example 1
ExtentTest parent = extent.createTest("Parent");
parent.createNode("Regression").pass("pass");
parent.createNode("Unit").fail("fail");
In the above example, the stats on the dashboard are viewed as:

// 2 charts: Tests, Steps
Total Tests = 1, tests passed = 0, tests failed = 1 // Parent (fail)
Total Steps = 2, steps passed = 1, steps failed = 1 // Regression (pass), Unit (fail)

View Report


Example 2

Now consider a different example without child tests:

ExtentTest parent1 = extent.createTest("Parent1");
parent1.pass("pass");
ExtentTest parent2 = extent.createTest("Parent2");
parent2.fail("fail");

In this example, since there are no children or steps, the dashboard displays 1 chart as:

// 1 chart: Tests
Total Tests = 2, tests passed = 1, tests failed = 1

View Report


Example 3

Finally, if there are more than 2 levels, the top-most and the bottom-most (leaf) levels will only be considered.

ExtentTest parent = extent.createTest("Parent");
ExtentTest child = parent.createNode("Child");
child.createNode("Regression").pass("pass");
child.createNode("Unit").fail("fail");
child.createNode("Integration").pass("pass");
// you will see 2 charts: Tests, Steps
Total Tests = 1, tests passed = 0, tests failed = 1 // counts Parent
Total Steps = 3, steps passed = 2, steps failed = 1 // counts Regression, Unit, Integration

View Report


AnalysisStrategy.SUITE

This strategy generates stats for 3 levels: Suite, Test/Class, Step. If your test structure uses 2 or fewer levels, use the TEST strategy. If you are creating BDD tests, see AnalysisStrategy.BDD. Let's see Example-3 from the previous section using AnalysisStrategy.SUITE.

extent.setAnalysisStrategy(AnalysisStrategy.SUITE);

ExtentTest suite = extent.createTest("Suite");
ExtentTest clazz = suite.createNode("Class");
clazz.createNode("Regression").pass("pass");
clazz.createNode("Unit").fail("fail");
clazz.createNode("Integration").pass("pass");
// you will see 3 charts: Suite, Class, Test
Total Suites = 1, suites passed = 0, suites failed = 1
Total Classes = 1, classes passed = 0, classes failed = 1
Total Tests = 3, tests passed = 2, tests failed = 1

View Report


AnalysisStrategy.BDD

It is not required to explicitly set the AnalysisStrategy for BDD tests, it is configured internally if a BDD test is started.


Markup Helpers

A few helpers are provided to allow:

  • Code block
  • Table
  • Label
  • Card
  • External Link
  • Modal

Code block

ExtentTest test = extent.createTest("Code Blocks");

// xml
String code = "<root>" + 
		"\n    <Person>" + 
		"\n        <Name>Joe Doe</Name>" + 
		"\n        <StartDate>2007-01-01</StartDate>" + 
		"\n        <EndDate>2009-01-01</EndDate>" + 
		"\n        <Location>London</Location>" + 
	"\n    </Person>                    " + 
	"\n    <Person>" + 
		"\n        <Name>John Smith</Name>" + 
		"\n        <StartDate>2012-06-15</StartDate>" + 
		"\n        <EndDate>2014-12-31</EndDate>" + 
		"\n        <Location>Cardiff</Location>" + 
	"\n    </Person>" +
"\n</root>";
Markup m = MarkupHelper.createCodeBlock(code, CodeLanguage.XML);
test.pass(m);

// json
String json = "{'foo' : 'bar', 'foos' : ['b','a','r'], 'bar' : {'foo':'bar', 'bar':false,'foobar':1234}}";
test.pass(MarkupHelper.createCodeBlock(json, CodeLanguage.JSON));

// java chars
code = "\n\t\n\t\tText\n\t\n";
m = MarkupHelper.createCodeBlock(code);
test.pass(m);

Resulting markup:

Code blocks example

Label

String text = "extent";
Markup m = MarkupHelper.createLabel(text, ExtentColor.BLUE);

test.pass(m);
// or
test.log(Status.PASS, m);

Table

String[][] data = {
    { "Header1", "Header2", "Header3" },
    { "Content.1.1", "Content.2.1", "Content.3.1" },
    { "Content.1.2", "Content.2.2", "Content.3.2" },
    { "Content.1.3", "Content.2.3", "Content.3.3" },
    { "Content.1.4", "Content.2.4", "Content.3.4" }
};
Markup m = MarkupHelper.createTable(data);

test.pass(m);
// or
test.log(Status.PASS, m);

Card

String text = "This text will become part of a material card.";
Markup m = MarkupHelper.createCard(text, ExtentColor.CYAN);

test.pass(m);
// or
test.log(Status.PASS, m);

String url = "http://extentreports.com";
String name = "extent";
Markup m = MarkupHelper.createExternalLink(url, name);

test.pass(m);
// or
test.log(Status.PASS, m);

Modal

test.info(MarkupHelper.createModal("Modal text"));

Adapters

Adapters for TestNG and Cucumber are available to simplify Extent Framework's integration with test frameworks.


TestNG Adapter

The TestNG adapter allows hooking into the events raised by TestNG using its IReporter and ITestListener listeners. If you are using TestNG, it is highly recommended to use the adapter.

Refer this link for the plugin page.


Cucumber Adapters

Cucumber versions (2-4) have unique adapters which allow listening to events raised by Cucumber's EventListener and Formatter. If you are using Cucumber, it is highly recommended to use the relevant adapter for your version. Adapters:


Changelog

4.1.0

Improvements
  • [#18] Steps count in dashboard displays 0 even though there are logged steps
  • [#94] Cleanup tag view naming
  • [#103] AppendExisting functionality similar to version 3 API, via JsonFormatter and ExtentReports::createDomainFromJsonArchive
  • 
    JsonFormatter json = new JsonFormatter("target/test.json");
    extent.attachReporter(json);
    extent.createDomainFromJsonArchive("target/test.json");
    
  • [#107] ExtentSparkReporter's default view is SPA, similar to V3HtmlReporter. This can be changed by instantiating as new ExtentSparkReporter("dir", ViewStyle.DEFAULT);
  • [#108] All resources migrated to jsDelivr
Fixes
  • [#57] ExtentKlovReporter: Screenshot cannot be saved in base64 format
  • [#101] Fixes Freemarker templating error
Improvements
  • [#35] HtmlReporter, BDD: description to appear as tooltip instead of newline
  • [#36] SparkReporter: display ScenarioOutline children as toggles
  • [#37] SparkReporter: auto-size textarea on click
  • [#42] CategoryView status toggles
Fixes
  • [#39] Test case name overlap test case timestamp Spark Reporter
  • [#40] Author & device name don't have a background label
  • [#43] SparkReporter: issue with setCSS not working
Fixes
  • [#31] ExtentHtmlReporter does not display devices
  • [#32] ExtentSparkReporter freemarker issue when injecting custom js
  • [#33] ExtentSparkReporter dark theme fix
Fixes
  • [#6] Invalid testEndTime and timeTaken
  • [#21] Adds ResourceCDN to use ExtentReports instead of cdn.rawgit
  • [#24] Timeline is broken because commas appear in duration
  • [#29] Embedded screenshot is missing in html report
  • [#30] Skipped tests not being displayed in HtmlReporter's tags view

4.0.6

Fixes
  • [#testng-adapter-1] Fixes issue where test start and end times were created as per the IReporter time of execution
  • [#12] Chart increasing in size when resizing browser window

4.0.5

Improvements
  • Several layout improvements for BDD view
Fixes
  • Adds missing ScreenCapture for steps

4.0.4

Fixes
  • Issue with BDD view showing charts in 2 rows

4.0.3

Fixes
  • Fixes build configuration

4.0.2

New
  • Add support for LoggerReporter to navigate from Category/Bug view to Test view
Fixes
  • [#6] Fix issue where total time taken was 0
  • [#7] Fix issue where markup was not parsed correctly in code blocks

4.0.1

New
  • [#4] Add support for Asterisk (*), BDD/Gherkin
  • [#5] Auto-size pre/textarea/code size upon click
Fixes
  • Disable checking for media existence as its causing issue with several Cucumber1 users

4.0.0

Initial release