Logging is very important in selenium framework, it helps us to understand the code, it helps a lot while debugging, and lot many other advantages.
For logging the message in selenium, we have multiple options. One way is to use Log4J API.
Refer below post to know how can we do logging using Log4j.
Another way to perform logging is, with the help of ITestListener interface of TestNG.
To achieve this, we need to trigger an event (of capturing screen shot) whenever any test case fails.
We can use testng listener for this purpose.
Once we implement ITestListener interface, below methods are created –
onFinish -> you can write some message here which will be written in to log file after finishing execution.
onStart -> you can write some message here which will be written in to log file after execution starts.
onTestFailedButWithinSuccessPercentage -> written in to log file after test failed, but within success percentage.
onTestFailure -> you can write some message here which will be written in to log file if test fails.
onTestSkipped -> you can write some message here which will be written in to log file if test skips.
onTestSuccess -> you can write some message here which will be written in to log file after successful execution of test.
Let us see how can we use ITestListener
Basically, ITestListener is an interface, which we need to implement in our class.
Follow these steps to take screen shot of failed test cases only.
1. Create sample class & implement ITestListener
2. After implementation, various methods are created. Put the proper message as required.
3. Define listener either in testng.xml (if you want to apply this for all the classes which are going to execute from testng.xml) or in the class which contains testng tests (if you want to apply this to only some specific class)
4. That’s it, all done. Refer below code & screenshots.
Create a sample class and implements ITestListener in it.
When you import ITestListener in the class, you will see option to implement unimplemented methods.
Refer below screen shot.
Once clicked on “Add unimplemented methods”, all methods will be implemented, code will look like –
package screenshotOfFailedTest;
import org.testng.ITestContext;
import org.testng.ITestListener;
import org.testng.ITestResult;
public class ListenerClass implements ITestListener {
@Override
public void onFinish(ITestContext arg0) {
// write the logging code here which will be executed on test finish
log("Test Finished....");
}
@Override
public void onStart(ITestContext arg0) {
// write the logging code here which will be executed on test start
log("Test Started....");
}
@Override
public void onTestFailedButWithinSuccessPercentage(ITestResult arg0) {
// write the logging code here which will be executed on test failure within success %
log("Test failed but is within....");
}
@Override
public void onTestFailure(ITestResult arg0) {
// write the logging code here which will be executed on test failure
log("Test failed....");
}
@Override
public void onTestSkipped(ITestResult arg0) {
// write the logging code here which will be executed on test skip
log("Test Skipped....");
}
@Override
public void onTestStart(ITestResult arg0) {
// write the logging code here which will be executed on test start
log("Test Started....");
}
@Override
public void onTestSuccess(ITestResult arg0) {
// write the logging code here which will be executed on test success
log("Test completed successfully....");
}
}
In the above code, ITestResult is an interface which keeps all information about test case which is being executed. It captures some information like Test case execution status, test case name etc.
Note: Using ITestResult is variable, we can get various states / information about current test, which is under execution, like – arg0.getName(), arg0.getMethod().getPriority()
Refer below code in which we will use above defined Listener.
package screenshotOfFailedTest;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.Assert;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
@Listeners (screenshotOfFailedTest.ListenerClass.class)
public class SampleTest {
public static WebDriver driver;
@Test
public void TestCase(){
driver = new FirefoxDriver();
driver.navigate().to("https://learnaboutsoftwaretesting.blogspot.in/");
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.manage().window().maximize();
driver.findElement(By.xpath("invalidXpath")).click(); //using invalid xpath so that test will fail & we can invoke ITestListener.
}
}
So, in above program, test is failing, since listener is used there, onTestfailure() method will execute.
Note: We need to mention somewhere about listenerclass in our test case. There are 2 ways to do so. You may like to do this at class level (this will be applicable to all test cases in that class) or you may like to do this at suite level (which will be applicable to whole suite. You need to define this in testng.xml file).
In above example. I have done it for class level by adding below line of code for listener.
@Listeners(screenshotOfFailedTest.ListenerClass.class)
Hope this helps !!!!!