In our previous post , we have seen list of testNG listeners and also we have seen how we can customise the output using the ITestListener.
In this post we will be talking about some more customisation using IReporter.
IReporter is an interface, we need to implement generateReport()
This method has 3 parameters, xmlSuites | suites | outPutDirectory
we will be dealing with parameter List<ISuite> suites, this contains all the suites inside the testng.xml which will have all the tests.
Let’s have 2 testNG classes
TestNG1.java
package mypkg;import org.testng.SkipException;import org.testng.annotations.Test;public class TestNG1 {@Test(description = "Desc - Passing a scenario")public void passTestMethod() {System.out.println("Inside PassTestMethod");}@Test(description = "Desc - Failing a scenario")public void failTestMethod() {int a = 9/0;System.out.println("Inside FailTestMethod");}@Test(description = "Desc - Skipping a scenario")public void skipTestMethod() {throw new SkipException("Intentionally skipping");}}
TestNG2.java
package mypkg;import org.testng.Assert;import org.testng.annotations.Test;public class TestNG2 {@Testpublic void Test1_2(){System.out.println("This is Test1_2: TESTNG3");Assert.fail();}@Testpublic void Test2_2(){System.out.println("This is Test2_2: TESTNG2");}}
Now let’s create another class for the implementation IReporter
IReporterManager.java
package mypkg;import org.testng.*;import org.testng.xml.XmlSuite;import java.util.Collection;import java.util.List;import java.util.Map;public class IReport implements IReporter {@Overridepublic void generateReport(List<XmlSuite> xmlSuites, List<ISuite> suites, String outputDirectory) {for (ISuite suite : suites) {System.out.println("Suite name - " + suite.getName());Map<String, ISuiteResult> suiteResults = suite.getResults();for (ISuiteResult sr : suiteResults.values()) {ITestContext tc = sr.getTestContext();System.out.println("Test tag name: " + tc.getName() +"Test start time: " + tc.getStartDate() +"Test end time: " + tc.getEndDate() +"Test report output dir: " + tc.getOutputDirectory());Collection<ITestNGMethod> failedMethods = tc.getFailedTests().getAllMethods();System.out.println("Total failed methods: "+ failedMethods.size() +" and those are: ");for(ITestNGMethod itm : failedMethods){System.out.println("Method description: " + itm.getDescription() + " Name: " + itm.getMethodName());}System.out.println("Passed tests for suite is :" + tc.getPassedTests().getAllResults().size());System.out.println("Failed tests for suite is :" + tc.getFailedTests().getAllResults().size());System.out.println("Skipped tests for suite is:" + tc.getSkippedTests().getAllResults().size());}}System.out.println("Path - " + outputDirectory);}}
Like ITestListener, IReporter can be integrated with testNG classes in 2 ways
Class level
Suite level
Class level
@Listeners(mypkg.IReporterManager.class)
public class TestNG2 {
....
@Listeners(mypkg.IReporterManager.class)
public class TestNG2 {
....
We can run individually the testng classes to see the output.
Suite level
Listeners can be specified on the testng.xml, so all the tests mentioned under the suite or test tag will be covered
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd" ><suite name="MySuite_Reporter" verbose="1" ><listeners><listener class-name="mypkg.IReporterManager"/></listeners><test name="Regression1" ><classes><class name="mypkg.TestNG1"/></classes></test><test name="Functional" ><classes><class name="mypkg.TestNG2"/></classes></test></suite>
Run the testng.xml – Right click on the xml > Run As > TestNG Suite
OutPut –
java.lang.ArithmeticException: / by zeroat testNG.TList.iTestList.TestNG1.failTestMethod(TestNG1.java:19)at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.base/java.lang.reflect.Method.invoke(Method.java:566)...Inside PassTestMethodTest ignored.This is Test1_2: TESTNG3java.lang.AssertionError: nullat org.testng.Assert.fail(Assert.java:97)at org.testng.Assert.fail(Assert.java:102)at testNG.TList.iTestList.TestNG2.Test1_2(TestNG2.java:13)at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)...This is Test2_2: TESTNG2===============================================MySuite For ListTotal tests run: 5, Passes: 2, Failures: 2, Skips: 1===============================================Suite name - MySuite_ReporterTest name - Regression1Test start time - Wed Oct 07 17:01:54 IST 2020Test end Time - Wed Oct 07 17:01:54 IST 2020Test report dir - /Users/skpatro/SelTraining_oct20/Repo/test-output/MySuite For ListNo. of failed tests - 1Failed methods are -Description - Desc - Failing a scenarioTest method name - failTestMethodFailed test no.1Passed test no.1Skipped test no.1Test name - FunctionalTest start time - Wed Oct 07 17:01:54 IST 2020Test end Time - Wed Oct 07 17:01:54 IST 2020Test report dir - /Users/skpatro/SelTraining_oct20/Repo/test-output/MySuite For ListNo. of failed tests - 1Failed methods are -Description - Test method name - Test1_2Failed test no.1Passed test no.1Skipped test no.0Process finished with exit code 0
You will observe the section after the default output, that is from the IReporterManager implementation for both the test tags.
If this post is useful, then refer ITestListener for more customisations.
You can combine ITestListener & IReporter together, example
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd" ><suite name="MySuite_Reporter" verbose="1" ><listeners><listener class-name="mypkg.ITestListManager"/><listener class-name="mypkg.IReporterManager"/></listeners><test name="Regression1" ><classes><class name="mypkg.TestNG1"/></classes></test><test name="Functional" ><classes><class name="mypkg.TestNG2"/></classes></test></suite>
IReporter html report –
For the html report generated after running the tests with IReporter listener, you can find the report under current project directory > test-output/MySuite/MySuite_Reporter.html
1 Comment