Listeners:
Listeners are whom that listen to you.If you talk about Webdriver
Listener so you should make a note of some classes and interfaces that we will
use.
- WebDriverEventListener – This is an interface, which have some predefined methods so we will implement all of these methods.
- EventFiringWebDriver- This is an class that actually fire Webdriver event
If you talk about Webdriver we
are doing some activity like type, click, navigate etc this is all your events
which you are performing on your script so we should have activity which
actually will keep track of it.
Take an
example if you perform click then what should happen before click and after
click.To capture these events we will add listener that will perform this task
for us.
What is TestNG listener and How
to implement in Selenium
When we talk
about TestNG Listener we will use ITestListener Interface.This
interface has some methods which we need to override as per our requirement.
For
example- take some method of ITestListener
@Override
public void onFinish(ITestContext arg0) {
}
@Override
public void onStart(ITestContext arg0) {
}
@Override
public void
onTestFailure(ITestResult arg0) {
} etc
How to implement TestNG
Listener
Its not that
tough as compared to WebDriver Listeners we simply have to implement ITestListener interface
and override all method as per requirement and its not required that you should
have some statements in all methods but yes you should use some of that method
Wisely
Scenario-
- If testcase is failing then what action should be performed
- If testcase is skipped then what should be action requested and so far..
STEP 1- CREATE A SIMPLE CLASS AND
IMPLEMENT ITESTLISTENER LISTENER
STEP 2- OVERRIDE ALL UNIMPLEMENTED METHODS
Once you implement all your java
program will look like
package testngDemo;
import
org.testng.ITestContext;
import
org.testng.ITestListener;
import
org.testng.ITestResult;
public class
ListenerDemoExample implements ITestListener{
@Override
public
void onFinish(ITestContext arg0) {
// TODO Auto-generated method stub
}
@Override
public
void onStart(ITestContext arg0) {
// TODO Auto-generated method stub
}
@Override
public
void onTestFailedButWithinSuccessPercentage(ITestResult arg0) {
// TODO Auto-generated method stub
}
@Override
public
void onTestFailure(ITestResult arg0) {
// TODO Auto-generated method stub
}
@Override
public
void onTestSkipped(ITestResult arg0) {
// TODO Auto-generated method stub
}
@Override
public
void onTestStart(ITestResult arg0) {
// TODO Auto-generated method stub
}
@Override
public
void onTestSuccess(ITestResult arg0) {
// TODO Auto-generated method stub
}
}
So let me implement some of the methods
and I will start my test.
I will override following method onTestStart, onTestSuccess(),
onTestFailure()
I have written a small test for facebook login and I am failing this
testcase forcefully so that we can check how different events will be fired if
testcase pass or fail
PROGRAM
package testngDemo;
import
org.openqa.selenium.By;
import
org.openqa.selenium.WebDriver;
import
org.openqa.selenium.firefox.FirefoxDriver;
import
org.testng.ITestContext;
import
org.testng.ITestListener;
import
org.testng.ITestResult;
import
org.testng.annotations.Test;
public class
ListenerDemoExample implements ITestListener{
// This is
dummy tescase for facebook login
@Test
public
void loginFB(){
WebDriver driver=new FirefoxDriver();
driver.get("http://www.facebook.com");
driver.manage().window().maximize();
driver.findElement(By.id("email")).sendKeys("mukesh@facebook.com");
driver.findElement(By.id("wronglocator")).sendKeys("dont-tell");
driver.findElement(By.id("loginbutton")).click();
}
@Override
public
void onFinish(ITestContext arg0) {
// TODO Auto-generated method stub
}
@Override
public
void onStart(ITestContext arg0) {
// TODO Auto-generated method stub
}
@Override
public
void onTestFailedButWithinSuccessPercentage(ITestResult arg0) {
// TODO Auto-generated method stub
}
@Override
public
void onTestFailure(ITestResult arg0) {
System.out.println("Screen shot
captured====="+arg0.toString());
}
@Override
public
void onTestSkipped(ITestResult arg0) {
// TODO Auto-generated method stub
}
@Override
public
void onTestStart(ITestResult arg0) {
// TODO Auto-generated method stub
System.out.println("TestCase started===="
+arg0.toString());
}
@Override
public
void onTestSuccess(ITestResult arg0) {
// TODO Auto-generated method stub
System.out.println("Congrates Testcase has been
passed===="+ arg0.toString());
}
}
STEP 3- IT NOT COMPLETED YET NOW WE NEED TO MODIFY
OUR XML FILE THAT IS KNOWN
AS TESTNG.XML AND WE HAVE TO SPECIFY THIS LISTENER AND WE HAVE TO EXECUTE
THAT XML FILE ONLY.
We have predefined listeners tag so that we
will use today.
<listeners>
<listener
class-name="testngDemo.ListenerDemoExample"/>
</listeners>
so your complete testng.xml file will look
like.
<?xml
version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM
"http://testng.org/testng-1.0.dtd">
<suite
name="Suite" parallel="none">
<listeners>
<listener
class-name="testngDemo.ListenerDemoExample"/>
</listeners>
<test
name="Test">
<classes>
<class name="testngDemo.ListenerDemoExample"/>
</classes>
</test> <!--
Test -->
</suite> <!-- Suite
-->
STEP 4- SIMPLE RUN THIS TESTNG.XML FILE AND ANALYZE THE
OUTPUT
Now if you analyze above output this event automatically
getting triggered like once testcase start and testcase failed or testcase
pass.
@listner is a testNG
annotation. This is one very important annotation if you chose to have some
default behavior for your test case when it fails, passes etc. For Eg : if you
extend TestListenerAdapter class and write your implementation in a custom
listner to override onTestFailure or onTestSuccess methods you will be able to
do pretty much anything you want when a test fails or passes, like taking
screenshots, writing something to database, sending emails etc.
Lets say your test fails and you want to rerun the test case automatically one more time when it fails. In that case you will be writing a custom listener to achieve what you need and plug the listener to your test case via @Listener annotation.
Lets say your test fails and you want to rerun the test case automatically one more time when it fails. In that case you will be writing a custom listener to achieve what you need and plug the listener to your test case via @Listener annotation.
what does they do?
listeners gives the flexibility for the user to listen to the events that are generated from the start of the execution of script till the end.
what kind of events?
events such as, when a test method goes into one of passed/failed/skipped state.
events such as, when a configuratiom annotated method goes into one of passed/failed/skipped state.
events such as before and after a annotated method is executed.
what is the actual purpose?
the main intention for providing listeners is to extend the default reports behaviour of TestNg. Extend this feature to generate your own custom reports by listening to the above events.
what else can you do?
unlimited possibilities: Few imp things such as,
Before the start of execution, Check if the server is up and running
Sending an automatic status mail at the end of execution
Any other task of your need
listeners gives the flexibility for the user to listen to the events that are generated from the start of the execution of script till the end.
what kind of events?
events such as, when a test method goes into one of passed/failed/skipped state.
events such as, when a configuratiom annotated method goes into one of passed/failed/skipped state.
events such as before and after a annotated method is executed.
what is the actual purpose?
the main intention for providing listeners is to extend the default reports behaviour of TestNg. Extend this feature to generate your own custom reports by listening to the above events.
what else can you do?
unlimited possibilities: Few imp things such as,
Before the start of execution, Check if the server is up and running
Sending an automatic status mail at the end of execution
Any other task of your need
Explaination2
Events are specific
actions that happen on something for e.g., button clicked! is an event. A
simple e.g., would be your mobile plays a sound everytime you get a call..
another event :) Incoming call is
an “event” here and your mobile playing a tune is the result of an “event
handler” being invoked :) [ Pats his back
for that innovative e.g., hehehehe !! Smile will you.. am trying to take away the
seriousness here.. sigh! ]
Listeners are basically those entities which are tuned into one
or more events that may arise.
TestNG has awesomely managed to leverage this concept and
provide a cleaner way of doing things.
So what are TestNG Listeners ?
They are basically “your” classes, which implement some
interfaces that TestNG provides, so that when TestNG raises certain events it
will look for all “classes” which are basically looking for such events and
call the respective event handlers in them.. Confused ??
Its ok to be confused ! I was confused to the core too.
So lets start off with a sample program which will show how to
use Listeners.
Here’s a sample Listener that
I created, which basically takes care of Starting and Stopping a Selenium
Server.
If you look at this listener, its no big complex thing. It is
just an ordinary class that implements an Interface named “ISuiteListener”.
Whenever a class implements this listener,
TestNG guarantees the end-user that it will invoke the methods
onStart() and onFinish() before and after running a TestNG Suite.
So before TestNG picks up your suite for execution, it first
makes a call to onStart() method and runs whatever has been scripted in this
method. In a similar way, it again makes a call to onFinish() method after a
suite has been run.
So what other listeners are there in TestNG ?
There are a lot of listeners. But I will give you an over view
on the most common listeners that you would need :
·
org.testng.IReporter : Implement this listener
within your class, if you want to customize the TestNG reports (for e.g., you
might want your test reports to be available as an excel sheet or a word
document or even a pdf for that matter). This would be the last of the calls
that TestNG makes before closing your execution.
·
org.testng.IInvokedMethodListener : Implement
this listener within your class, if you want something to be done before and
after a method is invoked by TestNG. Some classic examples would be,
instantiating and closing off the WebDriver for e.g.,.
·
org.testng.IInvokedMethodListener2 : Implement
this listener within your class if you want all that IInvokedMethodListener can
do, but also give you access to the ITestContext object. ITestContext object
essentially is the contextual representation of all the relevant information
for a given TestNG run.
·
org.testng.ITestListener : Implement this listener
within your class if you want to be notified before and after a test
(“<test>”) is run. This would also give you a way in which you can
specify as to what should be done when a particular test is
passed/skipped/failed etc., (A simple use case would be to implement some sort
of a running commentary on the console indicating how many tests have so far
run, how many passed and so on and so forth.
Ok, so now am guessing that you must be pretty aware of what
listeners are all about and we also saw how to write a listener. Now comes the
big question.
How do I let TestNG know that I have such a listener which it
should invoke when it is executing my tests ?
There are essentially
three ways of adding up a listener to a particular class. I will walk you
through on all of the three ways [at-least these are the only ways I know
of :) ] :
1. Using the @Listeners TestNG provided annotation.
This is the easiest way of binding your implemented TestNG
Listener to your test class.
Before your class definition, you just add up this listener as
below
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
@Listeners(SeleniumStarterListener.class)
public class IUseListeners {
private Selenium selenium = null;
@BeforeClass
public void
setup() {
selenium
= new DefaultSelenium("localhost",
4444, "*firefox", "http://www.google.com");
selenium.start();
}
@Test
public void
f() {
selenium.open("http://www.facebook.com");
}
@AfterClass
public void
tearDown() {
selenium.stop();
}
}
|
Here if you notice, I
am telling TestNG that for my test class “IUseListeners” I need TestNG to refer to the class SeleniumStarterListenerand invoke the corresponding methods within it
as and when a relevant TestNG “triggered” event happens. So in this case,
TestNG will first invoke my onStart() method in my Listener class before it
begins executing my Test (remember, that if you dont provide a suite for your
class as I have done here, TestNG creates a default suite, defines a default
Test and adds up your testclass to it). That is why I when you execute this
sample test along with the listener, the listener takes care of starting the
selenium server and stopping it. Clean way of doing it isn’t it ?? That is what
TestNG Listeners are there for :)
2. By using the <listeners> tag in your TestNG Template
file.
Although approach 1 is more than enough to get you started, it’s
not an “elegant” way of using Listeners, because you are forced to add this
@Listeners section to each of your classes, which you perhaps wont want. So
what you do is, you create a TestNG Suite file and then add up the listeners
section to this suite file. That way, all of your tests would essentially
leverage the listener that you wrote. So in our case, before the suite starts
(remember a suite can contain one or more suites within itself, one or more
tests within itself and each test<test> can have one or more test classes
in it).
So here’s how a typical xml file would look like :
1
2
3
4
5
6
7
8
9
10
11
12
|
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite" parallel="false">
<listeners>
<listener class-name="com.test.listeners.SeleniumStarterListener"/>
</listeners>
<test name="Test" preserve-order="false">
<classes>
<class name="com.test.IUseListeners" />
</classes>
</test>
</suite>
|
Pay close attention to
the <listeners> section here. I have defined this listener at the suite
level and have given the “fully qualified name”of my Listener class.
3. When you are working with TestNG class directly and want
to pro-grammatically run your Tests you can specify your Listeners as
below :
Here’s a sample code which shows you how to do this in a main()
program of Java.
1
2
3
4
5
6
7
|
public static void
main(String[] args){
TestNG testng = new TestNG();
Class[] classes = new Class[]{IUseListeners.class};
testng.addListener(new SeleniumStarterListener());
testng.setTestClasses(classes);
testng.run();
}
|
No comments:
Post a Comment