Extent Report 4 not creating report - java

I am trying to create extent report version v4.0.9 but unable to do so.
Below code I have written to setUp class which has all before method and aftermethos and the same class is extented to Utilities class where I am performing tests.
Here is code for setUp class
public class AIG_SetUp {
protected static ExtentLoggerReporter logger;
protected static ExtentReports extent;
protected static ExtentTest log;
#BeforeTest(alwaysRun = true)
public void starttest() {
logger = new ExtentLoggerReporter(System.getProperty("user.dir"));
extent = new ExtentReports();
extent.attachReporter(logger);
System.err.close(); // written to remove JAVA 9 incompatibility.. continued below
System.setErr(System.out); // continue.. and remove the warnings
extent.setSystemInfo("User Name" , "Sobhit");
}
#AfterMethod(alwaysRun = true)
public void endReport(ITestResult result) {
try {
if (result.getStatus() == ITestResult.FAILURE) {
log.log(Status.FAIL , "Test cases Failed" + result.getName());
log.log(Status.FAIL , "Test cases Failed" + result.getThrowable());
} else if (result.getStatus() == ITestResult.SKIP) {
log.log(Status.SKIP , "Test case skipped is" + result.getName());
}
} catch (Exception e) {
e.printStackTrace();
}
}
#AfterTest(alwaysRun = true)
public void endReport() {
extent.flush();
}
}
And here is the utilities class which is extented to above class.
public class UtilitiesOps extends AIG_SetUp {
#Test(groups = {"Core-Smoke"}, description = "List all media types")
public void Verify_List_all_media_types() {
extent.attachReporter(logger);
extent = new ExtentReports();
log = extent.createTest("List all media types");
log.assignCategory("Utilities Operations");
}
Couple of important points to mention
Now I am not getting error, before I was getting null pointer exception but now no error.
Also Code runs fine but not generating the extent report.
If I put everything in one class with no before test and stuff, able to create the report. Not sure why is going wrong.
I really appreciate your help.

I got answer for this after reading about it.
basically I was doing the beforetest without static variables where as it has to be statically intiated because of other global variables.
The below code fixed my issues.
#BeforeTest(alwaysRun = true)
public static void starttest() {
logger = new ExtentLoggerReporter(System.getProperty("user.dir"));
extent = new ExtentReports();
extent.attachReporter(logger);
System.err.close(); // written to remove JAVA 9 incompatibility.. continued below
System.setErr(System.out); // continue.. and remove the warnings
extent.setSystemInfo("User Name" , "Sobhit");
}

Related

Increase code coverage on method local objects or 3rd party library objects creation or 3rd party functions call

I have to unit test the below method, whereas all the lines of this code related to third party aws library. The method also returns nothing. So only test I can do is verifying the exception. Any other test can I do to improve the code coverage?
public void multipartUpload() throws InterruptedException {
TransferManager tm = TransferManagerBuilder.standard()
.withS3Client(s3Client)
.withMultipartUploadThreshold(1024l)
.build();
PutObjectRequest request = new PutObjectRequest(bucketName, keyName, filePath);
Upload upload = tm.upload(request);
upload.waitForCompletion();
}
Let see the code that needs to be tested:
public class DemoCodeCoverage {
public void showDemo(LibraryCode library) {
System.out.println("Hello World!");
library.runDemoApplication();
// Extract the below code to a method since LibraryCode is not passed
// Then ignore running that method
// LibraryCode library = new LibraryCode()
// library.runDemoApplication_1();
// library.runDemoApplication_2();
// library.runDemoApplication_3();
System.out.println("World ends here!");
}
public boolean showBranchingDemo(boolean signal) {
if (signal) {
signalShown();
} else {
noSignal();
}
return signal;
}
public void signalShown() {
System.out.println("signalShown!");
}
public void noSignal() {
System.out.println("NoSignal!");
}
}
public class LibraryCode {
// Library can be AWS/Database code which needs authentication
// And this authentication is not a concern for our UT
// Still will end up execption when we do our UT
public void runDemoApplication() {
throw new RuntimeException();
}
}
Below can give good code coverage:
public class DemoCodeCoverageTest {
#Test
public void testShowDemo() {
DemoCodeCoverage t = Mockito.spy(new DemoCodeCoverage());
LibraryCode lib = Mockito.mock(LibraryCode.class);
Mockito.doNothing().when(lib).runDemoApplication();
t.showDemo(lib);
// when(bloMock.doSomeStuff()).thenReturn(1);
// doReturn(1).when(bloMock).doSomeStuff();
}
#Test
public void testShowBranchingDemo() {
DemoCodeCoverage t = Mockito.spy(new DemoCodeCoverage());
assertEquals(true, t.showBranchingDemo(true));
assertEquals(false, t.showBranchingDemo(false));
}
#Test
public void testSignalShown() {
DemoCodeCoverage t = Mockito.spy(new DemoCodeCoverage());
t.showBranchingDemo(true);
Mockito.verify(t, times(1)).signalShown();
}
#Test
public void testNoSignal() {
DemoCodeCoverage t = Mockito.spy(new DemoCodeCoverage());
t.showBranchingDemo(false);
Mockito.verify(t, times(1)).noSignal();
}
}
Below are the steps to increase the test code coverage:
Case_1: Testing void method
Assume you have method the does not take any params and return nothing.
public void printHelloWorld() {
System.out.println("Hello World")
}
Still you can write test that calls this method and returns successfully without any runtimeException.
Actually we haven't tested anything here other than giving a option to run the code by our tests. Thus increase the code coverage.
Additionally you can verify the invocation:
Mockito.verify(instance, times(1)).printHelloWorld();
There are circumstances you cannot test those, example say it is third party library call, then the library might have tested already, we just need to run through it.
#Test
public void testPrintHelloWorld() {
// may be hibernate call/other 3rd party method call
instance.printHelloWorld();
}
If your tool is not strict for 100% code coverage, you can even ignore it and justify it.
Case_2: Testing a method with object created and called another method inside the testing method
Assume you have method the does call DB to add entry in Hello_World table also prints it in console like below.
public void printHelloWorld() throws DBException {
DBConnection db = new DBConnection();
db.createEntry(TABLE_NAME, "Hello World");
System.out.println("Hello World")
}
You can extract those db code into new method, then test it separately.
public void printHelloWorld() throws DBException {
makeHelloWorldEntryInTable();
System.out.println("Hello World")
}
public void makeHelloWorldEntryInTable() throws DBException {
DBConnection db = new DBConnection();
db.createEntry(TABLE_NAME, "Hello World");
}
While testing with DB you would expect the DBConnectionException as it is just unit test. So one test with #Test(expected=DBException) for makeHelloWorldEntryInTable, and another test on printHelloWorld() with skipping the method makeHelloWorldEntryInTable call like below. Thus increases the code coverage.
#Test(expected=DBException)
public void testMakeHelloWorldEntryInTable() {
//This can any third party library which cannot be configured for ut.
//One example is testing the AWS bucket exist or not.
instance.makeHelloWorldEntryInTable();
}
#Test
public void testPrintHelloWorld() {
Mockito.doNothing()
.when(localInstance)
.makeHelloWorldEntryInTable();
localInstance.printHelloWorld();
}
Case_3: if you have private method, then make it default package level and test it. Thus improves the code coverage.

How do i screenshot chrome browser when my tests fail and before the chrome browser closes (#After)

I have ran this code and the screenshot gets captured after the chrome browser closes (#After)
If i comment out CloseBrowser(); the screenshot gets captured but the chromebrowser stay open.
I want the screenshot to capture on a failed test then close the browser.
in summary
The screenshot currently captures after the browser closes, which is just a blank .png
I want the screenshot to capture when a test fails just before the browser closes
Thanks
public class TestClass extends classHelper//has BrowserSetup(); and CloseBrowser(); {
#Rule
public ScreenshotTestRule my = new ScreenshotTestRule();
#Before
public void BeforeTest()
{
BrowserSetup();// launches chromedriver browser
}
#Test
public void ViewAssetPage()
{
//My test code here//And want to take screenshot on failure
}
#After
public void AfterTest() throws InterruptedException
{
CloseBrowser();//closes the browser after test passes or fails
}
}
class ScreenshotTestRule implements MethodRule {
public Statement apply(final Statement statement, final FrameworkMethod frameworkMethod, final Object o) {
return new Statement() {
#Override
public void evaluate() throws Throwable {
try {
statement.evaluate();
} catch (Throwable t) {
captureScreenshot(frameworkMethod.getName());
throw t; // rethrow to allow the failure to be reported to JUnit
}
}
public void captureScreenshot(String fileName) {
try {
new File("target/surefire-reports/").mkdirs(); // Insure directory is there
FileOutputStream out = new FileOutputStream("target/surefire-reports/screenshot-" + fileName + ".png");
out.write(((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES));
out.close();
} catch (Exception e) {
// No need to crash the tests if the screenshot fails
}
}
};
}
}
You can implement TestNG Listeners to execute code before a test or after a test
Or when a test fails or succeeded etc.
Implement it like below and put your screenshot in the method i showed
public class Listeners implements ITestListener {
Methods…
And put the screenshot code inside the method below:
#Override
public void onTestFailure(ITestResult result) {
code for screenshot
}
}
So i have found a way to implement the screenshots. I have created a method that will take a screenshot. I have put a try and catch around my test code and catch an exception and calling the method to take a screenshot.
public class TestClass extends classHelper//has BrowserSetup(); and CloseBrowser(); {`
#Rule
public ScreenshotTestRule my = new ScreenshotTestRule();
#Before
public void BeforeTest()
{
BrowserSetup();// launches chromedriver browser
}
#Test
public void ViewAssetPage()
{
try
{
//My test code here//And want to take screenshot on failure
}
catch(Exception e)
{
//print e
takeScreenShot();
}
}
#After
public void AfterTest() throws InterruptedException
{
CloseBrowser();//closes the browser after test passes or fails
}
}
///////////////////////////////////////////
void takeScreenShot()
{
try
{
int num = 0;
String fileName = "SS"+NAME.getMethodName()+".png";//name of file/s you wish to create
String dir = "src/test/screenshot";//directory where screenshots live
new File(dir).mkdirs();//makes new directory if does not exist
File myFile = new File(dir,fileName);//creates file in a directory n specified name
while (myFile.exists())//if file name exists increment name with +1
{
fileName = "SS"+NAME.getMethodName()+(num++)+".png";
myFile = new File(dir,fileName);
}
FileOutputStream out = new FileOutputStream(myFile);//creates an output for the created file
out.write(((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES));//Takes screenshot and writes the screenshot data to the created file
//FileOutputStream out = new FileOutputStream("target/surefire-reports/" + fileName);
out.close();//closes the outputstream for the file
}
catch (Exception e)
{
// No need to crash the tests if the screenshot fails
}
This might help:
https://github.com/junit-team/junit4/issues/383
The ordering for rule execution has changed with new 'TestRule'

Get log message from Assertions

I'm integrating html-reports to our test framework using Extent Report library (version 4).
For that purpose I wrote a wrapper, that encapsulates our default TestNG logger (for the console output) and ExtentReport logger (ExtentTest.log, to collect data for html-report).
We use TestNg as our testing framework.
Having an issue capturing log messages from failed assertions (both soft and hard Assertions) to display it in html-report, they go only to the console log.
What would be the possible solution to capture those Assert log messages to show them in html-report?
I can't extend Assert (or SoftAssert) classes and add my own implementation (by adding an instance of ExtentTest.log there) because I'd have to replace all assertions in dozens of tests.
public class Loggers {
private static final Loggers instance = new Loggers();
private static ExtentTest test;
private static ExtentReports extent;
private static Logger LOG;
private static final String REPORT_LOCATION = "test-output/reports.extent.html";
/**
* Returns an instance of {#link ExtentReports} object. If it doesn't exist creates a new instance and returns it
*/
public static ExtentReports getLogger() {
if ( extent == null ) {
createInstance();
}
return extent;
}
/**
* Create ExtentReport and attaches htmlReporter to it
*/
public static void createInstance() {
ExtentHtmlReporter htmlReporter = getHTMLReporter();
extent = new ExtentReports();
extent.attachReporter( htmlReporter );
}
/**
* This method creates, configures and returns an instance of ExtentHtmlReporter
*
*/
public static ExtentHtmlReporter getHTMLReporter() {
ExtentHtmlReporter htmlReporter = new ExtentHtmlReporter( REPORT_LOCATION );
return htmlReporter;
}
/**
* This method logs a message with the INFO level for both instances of TestNG Logger and ExtentTest
*/
public void info( String message ) {
LOG.info( message );
test.log( Status.INFO, message );
}
Found the solution. Will post here if somebody will have similar issue.
If you locate your loggers in a listener class, you can put your logger over there and use ITestResult as an argument, specifically its method getThrowable (It returns the throwable that was thrown while running the method)
/**
* Triggered upon the failure of a test
*/
public void onTestFailure( ITestResult testResult ) {
LOG.fail( testResult.getThrowable() );
}
It will print in the report a failed assertion or thrown exception.
The Below Code Works for me for Extent Report Try it!
1) Initialize Extent report and Logger
public static Logger log = Logger.getLogger("devpinoyLogger");
public ExtentReports rep = ExtentManager.getInstance();
public static ExtentTest test;
2) Use Configuration File ReportsConfig.xml for Extent Report that you can get from extentreports official site.
3) Create class ExtentManager that load config file and set output of Extent report file.
public class ExtentManager {
private static ExtentReports extent;
public static ExtentReports getInstance(){
if(extent==null){
System.out.println("Path of user DIR"+System.getProperty("user.dir"));
extent = new ExtentReports(System.getProperty("user.dir")+"\\target\\surefire-reports\\ExecutionReport.html",true,DisplayOrder.OLDEST_FIRST);
extent.loadConfig(new File(System.getProperty("user.dir")+"\\src\\main\\java\\extentconfig\\ReportsConfig.xml"));
}
return extent;
}
}
4) Use INFO and ERROR log in method you are creating to display logs in Extent report.
public void click(String xpath) {
try {
driver.findElement(By.xpath(Variables.OR.getProperty(xpath))).click();
System.out.println(xpath + "Button clicked");
test.log(LogStatus.INFO, xpath + " Button clicked");
Thread.sleep(1000);
} catch (Exception e) {
System.err.println("Cannot Click " + e.getMessage());
test.log(LogStatus.ERROR,"Unable to click on :: " + xpath + " Button");
throw new AssertionError("Unable to click on :: " + xpath + " Button", e);
}
}
5) Use Custom listener class CustomListeners
public class CustomListeners extends TestBase implements ITestListener, ISuiteListener {
public boolean flag;
..implement all methods of CustomListeners class and use logs in onTestSuccess and onTestFailure Methods.
public void onTestSuccess(ITestResult arg0) {
test.log(LogStatus.PASS, arg0.getName().toUpperCase() + " PASS");
rep.endTest(test);
rep.flush();
}
public void onTestFailure(ITestResult arg0) {
System.out.println(arg0 + " =================Test Case Failed===========================");
flag = true;
System.out.println("Flag is inside onTestFailure " + flag);
System.setProperty("org.uncommons.reportng.escape-output", "false");
try {
test.log(LogStatus.FAIL, arg0.getName().toUpperCase() + " Failed with exception : " + arg0.getThrowable());
rep.endTest(test);
rep.flush();
} catch (IOException e) {
System.err.println("IOException occurs " + e.getMessage());
e.printStackTrace();
}
}
}
ExtentReport view for PASS Test Case
ExtentReport view for FAIL Test Case

Selenium webdriver Page Object Pattern and ExtentReports

Someone could tell me how to write a functional application tests which combine Selenium Page Object Pattern and ExtentsReports (http://extentreports.relevantcodes.com/) to generate reports from these test cases. How to design test class? because I know that validation should be separated from page objects. What is the best approach to do this?
A sample piece of code would be very helpful
It is a good approach, of course, to separate your model (Page Objects) from you tests. For this to happen, you may use a layer of services, i.e. helper classes, which can interact both with business objects and page objects.
Note: I'm going to answer the second part of your question, not that on yet-another lib for reporting.
So, you have a business object:
public class Something {
boolean toHappen;
public Something(boolean toHappen) {
this.toHappen = toHappen;
}
public boolean isToHappen() {
return toHappen;
}
}
You also have your page:
public class ApplicationPage {
// how driver object is put here is your own business.
private static WebDriver driver;
#FindBy(id = "id")
private Button triggerButton;
public ApplicationPage() {
PageFactory.initElements(driver, this);
}
public static ApplicationPage open(){
driver.get("http://page.net");
return new ApplicationPage();
}
public void trigger() {
triggerButton.click();
}
}
So in order not to mix business objects and pages in tests, you create a service:
public class InevitableService {
public static void makeHappen() {
// just a very stupid code here to show interaction
Something smth = new Something(true);
ApplicationPage page = ApplicationPage.open();
if(smth.toHappen()){
page.trigger();
}
}
}
And finally your test
public class TestClass extends Assert {
#Test
public void test() {
InevitableService.makeHappen();
assertTrue(true);
}
}
As a result:
you have no driver in tests
you have no page objects in tests
you operate only high-level logic
Pros:
very flexible
Cons:
gets complicated over time
Considering your reporting tool - I believe it just listens the result of you tests and sends them to server. Or it just takes the xml/html results of you tests and makes pretty and useless pie-charts. Again, has nothing to do with POP.
Steps:
1. Declare variables under Test Suite class
public ExtentReports extent ;
public ExtentTest test;
2. Create object for Extent Managers User defined class
extent = ExtentManager.instance();
3. Pass extent parameter to the Page Object Class
inbound = new DemoPageObject(driver,extent);
4. Goto page object class method and Start with "Start log"
test = extent.startTest("View details", "Unable to view details");
5. For Success steps and we need end test
test.log(LogStatus.PASS, "The list of details are successfully displaying");
test.log(LogStatus.INFO, test.addScreenCapture(ExtentManager.CaptureScreen(driver, "./Send")));
log.info("The list of details are successfully displaying ");
extent.endTest(test);
6. For Failure and no need to end test
test.log(LogStatus.FAIL, "A Technical error is displaying under ");
7. Use #AfterMethod to handle error test cases
#AfterMethod
public void tearDown(ITestResult result) {
if (result.getStatus() == ITestResult.FAILURE) {
test.log(LogStatus.FAIL, "<pre>" + result.getThrowable().getMessage() + "</pre>");
extent.endTest(test);
}
}
8. Finally Adding results to the report
#AfterTest
public void when_I_Close_Browser() {
extent.flush();
}
public class ExtentManager {
public static ExtentReports instance() {
ExtentReports extent;
String Path = "./ExtentReport.html";
System.out.println(Path);
extent = new ExtentReports(Path, true);
//extent.config() .documentTitle("Automation Report").reportName("Regression");
extent
.addSystemInfo("Host Name", "Anshoo")
.addSystemInfo("Environment", "QA");
return extent;
}
public static String CaptureScreen(WebDriver driver, String ImagesPath) {
TakesScreenshot oScn = (TakesScreenshot) driver;
File oScnShot = oScn.getScreenshotAs(OutputType.FILE);
File oDest = new File(ImagesPath + ".jpg");
try {
FileUtils.copyFile(oScnShot, oDest);
} catch (IOException e) {
System.out.println(e.getMessage());
}
return ImagesPath + ".jpg";
}
}

Maximum coverage of JUnit Test case

Tests should have good coverage of the types of exceptions and errors that this class can throw, and it should have good coverage of the defective statements in the constructor method for CalculatePrimesMother.
The method for which three Junit test case needed is as below:
public CalculatePrimesMother(int numWorkers, int queueLength, int maxPrime,
boolean verbose) {
this.numWorkers = numWorkers;
// Instantiate 3 queues, for thread-safe communication with workers
Candidate = new ArrayBlockingQueue<Integer>(queueLength);
Prime = new ArrayBlockingQueue<Integer>(queueLength);
Composite = new ArrayBlockingQueue<Integer>(queueLength);
this.maxPrime = maxPrime;
this.sqrtMaxPrime = (int) Math.sqrt(maxPrime);
primeFactors = new int[sqrtMaxPrime];
this.verbose = verbose;
}
I tried and created some test case but not able to get full coverage can anyone help me?
public class CalculatePrimesMotherTest extends TestCase {
public CalculatePrimesMotherTest(String name) {
super(name);
}
private CalculatePrimesMother testMother;
#Test
public final void testCalculatePrimesMotherNegativequeueLength() {
try {
testMother = new CalculatePrimesMother(4, -12, 908, false);
} catch (Exception e) {
e.printStackTrace();
}
}
#Test
public final void testCalculatePrimesMotherMinusOne() {
try {
testMother = new CalculatePrimesMother(8, 12, 0, true);
} catch (Exception e) {
e.printStackTrace();
}
}
}
What coverage do you get? There are no if tests in your ctor, so a single call should exercise all the code that I see.
You're writing too much code. The setUp and tearDown and test constructor methods are all unnecessary. Remove them.
You don't need the try/catch blocks in the other tests. Remove those, too. You want an exception to trigger a test failure. Catching will hide the error.

Categories

Resources