Monday, December 27, 2010

Selenium full-fledged implementation

Selenium full-fledged implementation.

In order to implement full-fledge selenium for a project, you may require understanding on following tools and framework.

1. Selenium Core
2. Selenium RC
3. Java (Extending Classes and Implementing Interface)
4. Java Script
5. Eclipse IDE
6. TestNG
7. JUnit
8. Apache Ant
9. AutoIt V3
10. Flex-Pilot
11. Hudson-CI
12. Selenium GRID (optional)

---

Thursday, December 23, 2010

SeleniumRC -Flex/Flash Automation

SeleniumRC -Flex/Flash Automation

Automation of flex is very challenging when compared with normal HTML. As per my understanding no automation tool can recognize the flex objects directly without compiling the flex source code with additional libraries.

All the HTML objects are visible under page DOM, but the flex objects are not visible. Flex is displayed on the page by embedding .swf file in the HTML. As .swf file is proprietary to Adobe and having their own standards and design, object methods are not visible and understood outside. To expose the objects, we need to recompile the flex with some third party libraries.

Points to be considered while selecting third party OR open source libraries.
1. There should be slight increase of .swf file size (or Total Page Size) after the compilation with the additional libraries. This will impact the application performance when multiple users are accessing the page.
2. It should allow to test Flex and Html simultaneously.
3. It should not break the existing functionality and allow us to test in production and test environment.
4. Ability to expose all the flex objects (like Grid...)
5. Easy to code and identify the objects, instead of writing lengthy statements.

Some of the flex libraries for selenium are
1. flash-selenium
2. flexmonkium
3. flex-pilot

I have spent time on above said libraries and felt Flex-pilot is suitable to me. It has bootstrapeer to make application testable and use chains to identify the objects, similar to xpath.

Implementing Flex-pilot on your application, select this Link.
Make sure you don't have any compilation errors and deploy it on test environment.

Test whether flex-pilot bindings are created properly.
1. By using Sauce IDE. Download from this Link. (Firefox add-on)
2. By using firebug

Sauce IDE
Download and install as Firefox add-on. This is similar to Selenium IDE with additional Flex capabilities. It has got "FlexExplorer" that can locate the Flex object chains (xpath for flex-pilot). Open the application and navigate to flex component page, open the Sauce IDE, select the "FlexExplorer" button and locate any flex object, you should be seeing its chain. It is similar to GUI spy in QTP.
Attaching the screen shot for more clarity.

If it find Target value, then that is the main handle. Attaching the screen shot for more clarity.

Firebug
Best way to test your Flex code is by using the Firebug. Flex pilot bindings expose the flex objects methods in the page dom, so by using JavaScript you can simulate the changes on the flex screen without running the code through selenium.
From the above screen you can notice that "GepCatalog" is the main handle for the entire flex object. Type the following code in the firebug console and run it, if it says "Function" every thing is configured perfectly.
Attaching the screen shot for more clarity.

Following are the available API's, select this link.

You can get the object ids from the Flex explorer or flex developer can provide the ids for the objects you are planning to interact. Before moving to selenium, run the DOM script and make sure all the objects are identifiable. Attaching the screen shot for more clarity.

I hope you are comfortable identifying the flex objects, lets move to selenium.
You can run the same above methods in selenium in the following way.
s.runScript("document.getElementById('GepCatalog').fp_type({name:'txtSearch', text:'laptop'})");
s.runScript("document.getElementById('GepCatalog').fp_click({name:'goBtn'})");
If you want to run by using selenium directly without using page DOM.
Download "DefaultSelenium.Java" from the from this link, implementation of Selenium interface with additional flex methods.
Download "UserExtension.js" from this Link and run the selenium jar using this extension. For more details read this Post.
There will be slight change in the code, Selenium code looks like this.
private Selenium s = new ds( "localhost",4444,"*iexplore",BASE_URL);
---
((ds)s).flexType("id=GepCatalog", "text=laptop,chain=name:txtSearch");
((ds)s).flexClick("id=GepCatalog", "chain=name:goBtn");
Note: ds - DefaultSelenium.Java

Thanks a lot for Flex-Pilot contributors.
Enjoy Flex, Happy Testing!
---

Thursday, December 16, 2010

Selenium - Simulate Modal Dialog Pop-Up

Selenium - Simulate Modal Dialog Pop-Up

when user open a Modal dialog pop-up by selecting a link or button, focus on the parent window is lost and user is forced to act on the pop-up window and close it, before proceeding further. User can't even look at page view source during modal pop-up on the screen.

Selenium work by executing the JavaScript, when pop-up is displayed, parent window JavaScript execution capability is lost, naturally Selenium can't work.

What are the issues I came across?
1. I am not able to open the Modal Pop-Up using selenium, when I select the link I am getting error message, it work fine when I open the window manually with out Selenium. My Modal pop-Up contain complex Ajax functionality that is conflicting with the Selenium Core when I select the pop-up link.
Attaching error screen shot for more clarity.

2. Values returned by the pop-up are mandate fields, I cant submit the page without these values.

I started searching in Google, but there is no solution. I do not have enough time to debug the selenium core and understand why it is conflicting with the application. Need to some how manage with out opening the pop-up. Then I started looking at the view source and understood the return values of the pop-up.
Attaching screen shot of the call statement to modal pop-up from page view source.


                          
Then I though, why can't I update the values directly in the page DOM, so that it is not even required to open the pop-up. Then I could succeed injecting the values and simulated the modal pop-up dialog.
Attaching the Selenium code
String JS =
               "{" +
               " this.page().findElement('id=ctl00_Cphe_txtSuppName').value='Supplier1';" +
               " this.page().findElement('id=ctl00_Cphe_hdnVendorId').value='1267';" +
               " this.page().findElement('id=ctl00_Cphe_hdnContactId').value='233';" +
               "}"; 
      s.getEval(JS);
I hope this post can help people having issues with modal pop-up.
Enjoy!


Monday, December 6, 2010

Selenium UserExtension - RC vs IDE

Selenium UserExtension - RC vs IDE

There are slight differences between Selenium RC and IDE JavaScript functions. Below example will help you in converting the function from one format to another.

Timer extension for IDE from Wiki Link.
var globalTime = new Object();
Selenium.prototype.doTimerStart = function(target) {
 var dt1 = new Date();
 if (target == null || target == "")
 {
  LOG.info ("Target not present so timer was not started");
 } else {
  globalTime[target] = dt1;
 }
 delete dt1;
};
Selenium.prototype.doTimerStop = function(target) {
 var dt = new Date();
 if (target == null || target == "")
 {
  LOG.info ("Please specify a target");
 } else if (globalTime [target] == null) {
  LOG.info ("Start time was not called for " + target);
 } else {
   LOG.info ("Time Passed for " + target + " : " + Math.floor (
dt - globalTime[target]));
  delete globalTime[target]; }
 delete dt;
};

The same above functions converted into RC format
var globalTime = new Object();
Selenium.prototype.getTimerStart = function(target) {
 var dt1 = new Date();
 if (target == null || target == "")
 {
  return  ("Target not present so timer was not started");
 } else {
  globalTime[target] = dt1;
  return null;
 }
 delete dt1;
};

Selenium.prototype.getTimerStop = function(target) {
 var dt = new Date();
 if (target == null || target == "")
 {
  return  ("Please specify a target");
 } else if (globalTime [target] == null) {
   alert("called");
  return  ("Start time was not called for " + target);
 } else {
   return  ("Time Passed for " + target + ":" + Math.floor (dt - globalTime[target]) + " msec");
   delete globalTime[target]; 
  }
 delete dt;
};

How to call this function from Java, read this Link.

---

Thursday, December 2, 2010

Selenium timer extension

Selenium timer extension

Selenium don't provide built in timer objects to calculate the page response time or page load time.
You need to extend the functionality by using Java script or by Java language.

Selenium timer extension for IDE is provided at Link.
Above Java script don't work on Selenium RC, so I have modified the Java Script and placed in the following Link.

I prefer using timers in Java language, you can find the sample code in this Link.

---

Selenium RC - User Extension.JS

Selenium RC - User Extension.JS

As a Selenium programmer you may require to create new methods or functions that doesn't exist.
One of the best method is by using UserExtension.js. In future posts I will explain about extending the existing selenium class.

Add following libraries to your project, attaching the snap shot.


Create new java class using following code. This example is created on google.com, so that any one can execute the code with out any issues.

What is this program about ?
1. Created new Method "MyClick".
2. Two new functions to calculate page response time (timerStart, timerStop).
3. Open the google page, search for an item and display page response time in Milli seconds for the results page.
Initially I had lot of issues while working with user-extensions, I want to bring clarity to my users by providing this example. There are differences between IDE and RC extensions, read my timer extension post for better understanding.

package package1;

import static org.testng.AssertJUnit.*;
import org.testng.annotations.*;
import com.thoughtworks.selenium.*;


public class Sample2
{
    private static final String Timeout = "30000";
    private static final String BASE_URL = "http://google.com/";
    private static final String BASE_URL_1 = "/";
    private Selenium selenium;
    private HttpCommandProcessor proc;
    
    @BeforeClass
    protected void setUp()throws Exception
    {
       proc = new HttpCommandProcessor("localhost", 4444, "*iexplore", BASE_URL);
       selenium = new DefaultSelenium(proc);     
       selenium.start();
       selenium.windowFocus();
       selenium.windowMaximize();
       selenium.windowFocus();
    }
    
    @AfterClass(alwaysRun=true)
    protected void tearDown() throws Exception
    {
       selenium.stop();
    }
    
    @Test(groups="search")
    public void test_GoogleSearch() throws Exception
    {
     selenium.open(BASE_URL_1);
     selenium.type("name=q", "selenium HQ");
     System.out.println(proc.doCommand("getTimerStart",new String[] {"GooglePage"}));
     //selenium.click("btnG"); //selenium command 
     proc.doCommand("myClick",new String[] {"btnG"}); //user extension for Click ()
     selenium.waitForPageToLoad(Timeout);
     System.out.println (proc.doCommand("getTimerStop",new String[] {"GooglePage"}));
     Thread.sleep(5000); //Show the page for few seconds 
    }
    @Test(groups="search")
    public void test_GoogleSearch1() throws Exception
    {
     selenium.open(BASE_URL_1);
     selenium.type("name=q", "Bharath Marrivada");
     System.out.println(proc.doCommand("getTimerStart",new String[] {"GooglePage"}));
     //selenium.click("btnG"); //selenium command
     proc.doCommand("myClick",new String[] {"btnG"}); //user extension for Click ()
     selenium.waitForPageToLoad(Timeout);
     System.out.println (proc.doCommand("getTimerStop",new String[] {"GooglePage"}));
     Thread.sleep(5000); //Show the page for few seconds 
    }    
}



UserExtension.js

Selenium.prototype.doMyClick = function(inputParams) 
{
 var element = this.page().findElement(inputParams);
 this.page().clickElement(element);
 return null;
};

var globalTime = new Object();
Selenium.prototype.getTimerStart = function(target) {
 var dt1 = new Date();
 if (target == null || target == "")
 {
  return  ("Target not present so timer was not started");
 } else {
  globalTime[target] = dt1;
  return null;
 }
 delete dt1;
};

Selenium.prototype.getTimerStop = function(target) {
 var dt = new Date();
 if (target == null || target == "")
 {
  return  ("Please specify a target");
 } else if (globalTime [target] == null) {
   alert("called");
  return  ("Start time was not called for " + target);
 } else {
   return  ("Time Passed for " + target + ":" + Math.floor (dt - globalTime[target]) + " msec");
   delete globalTime[target]; 
  }
 delete dt;
};
Note: Make sure you create the .js file in the selenium.jar folder.

To execute JavaScript functions from .js file, need to use  http command processor "proc.doCommand".
If the function is not returning any value start the function name with "do", else use "get".
Function names are case sensitive, always start with lower case. For "do" function, remove "do" while calling the function from Java.

To start the selenium server use following command.
java -jar selenium-server.jar -userExtensions user-extensions.js

To start the Selenium server quickly, every time instead of going into command prompt, I use following text saved as .vbs file. Double click the file, your selenium server will be up and running. (Modify the folder path)
Dim oShell
Set oShell = WScript.CreateObject ("WScript.Shell")
oShell.run "cmd /K CD C:\selenium-remote-control-1.0.3\selenium-server-1.0.3 & java -jar selenium-server.jar -userExtensions user-extensions.js"
Set oShell = Nothing

Enjoy!

For more information look at selenium documentation.
---

Wednesday, December 1, 2010

Selenium Documentation

Selenium Documentation

Tuesday, November 30, 2010

QTP License Server - Change IP Address

QTP License Server - Change IP Address

If you are planning to change the QTP licence Server IP adddress, perform following changes in the client machines. Attaching the screen shot for more clarity.


Make sure you are able to ping the IP from the client machine and QTP concurrent license server configured correctly.
---

Tuesday, November 23, 2010

Understanding ScriptResource and WebResource in ASP.NET

Understanding ScriptResource and WebResource in ASP.NET

While recording load test script on ASP.Net application, you may come across following files based on your code design. These files need to be parameterized, as the file URL contain time stamp in encrypted format and resource id. You may encounter multiple files in a single page with different URL parameters.

Attaching the files and URL screen shot.



A web resource is a file embedded in an assembly.  This file can either be a JavaScript file or a BMP, or any other emendable type of resource in an assembly. 

There are two basic ways to getting at your assembly resources loaded on your ASP.NET web page.  ScriptResource.axd and WebResource.axd.

The URL for WebResource.axd looks like the following:
WebResource.axd?d=SbXSD3uTnhYsK4gMD8fL84_mHPC5jJ7lfdnr1_WtsftZiUOZ6IXYG8QCXW86UizF0&t=632768953157700078
The format of this URL is WebResource.axd?d=encrypted identifier&t=time stamp value. The "d" stands for the requested Web Resource. The "t" is the timestamp for the requested assembly, which can help in determining if there have been any changes to the resource.

Some of the advantages of using these files
1. Automatically GZip/Compressing your scripts over HTTP for delivery.
2. Dynamically resolving Release/Debug scripts based on build parameters.  This is useful, if you keep two types of the same script: one for debug, and one packed for release.
3. Can be used for Non-MsAJAX Framework script assets such as jQuery.


Following are the links for better understanding of this post.


---



Wednesday, November 10, 2010

Software developers and testers: Can't we all just get along?

Software developers and testers: Can't we all just get along?


I felt this article interesting...just want to share with every one.

Developers and testers often have a contentious relationship. This isn't too surprising when you think about it. Part of the role of a traditional tester is to find out what's wrong with the code – something that the developer has most likely spent many long hours perfecting. The tester is criticizing his baby! Having spent years of my career in both roles, I'm well aware of the emotions on both sides of the equation. However, by learning some techniques, developers and testers can learn to avoid conflict and discover that they are often one another's most important ally.
Break down the wall
Both in agile methodologies and in application lifecycle management (ALM), there is the ever-growing trend of breaking down "silos" and becoming more collaborative. No longer are we to "throw code over the wall" between development and test. However, regardless of your organizational structure or methodology, I maintain that this "wall" does not need to exist. It is about attitude.
In an organization where there is a "wall," the developers and testers are critical of one another. The developers pass the code on to the test group. The test group pat themselves on the back for finding so many bugs, complain that the code was delivered to them too late with no unit test and that the project can never be released because the quality is so poor. The developers claim the bugs are user errors and that the testers are wasting time testing areas of code that aren't important. In general, these two groups are not respecting the value that they are each bringing to the table. Rather they are pointing fingers at one another, claiming the other is "the problem."
Even in organizations where the tension is not as pronounced, there can be a general lack of good communication between development and test. Working on agile teams where there is more of a partnership between a developer and tester helps, but it doesn't always solve the problem entirely.
Learn the craft of the other
One way to appreciate the value of your partner in a developer-tester relationship is to spend some time in the other's shoes. As I wrote in my response to a user question about the importance of code vs. test, they are both important. At the very least, a developer needs to learn how to thoroughly unit test his code. By also learning the art of exploratory testing and other testing skills, such as performance testing and security testing, the developer will know better how to design his code, not just for fewer defects, but for testability.
Likewise, the tester who learns the craft of software development will be highly valued. Not only will this tester be better equipped to help with automation of procedures and tests, but she will go beyond testing by being able to provide some insights into why a troublesome defect is occurring. Understanding the architecture of the application helps the tester make educated guesses about defects and then further test those guesses with additional testing, proving or disproving a hypothesis.
Use respectful communication
Regardless of your skill level, or that of your counterpart, in order to have an effective relationship, you must communicate with respect. In any job where the role is to assess and critique, it's important to communicate the findings with sensitivity and diplomacy. Though it's natural for a tester to feel proud of finding a major bug before it reaches production, there's no need to gloat about it, particularly if fixing that bug causes a major setback for the developer. Can you imagine a doctor communicating to his patient about a tumor he'd found? The patient might get rather annoyed if he came in with a big smile on his face saying, "Guess what I found? Maybe if you'd taken better care of yourself, this wouldn't have happened." What's more, the patient would want to know as much as possible about this tumor. The doctor not only has to deliver the news, but must do it with sensitivity and with plenty of data to back up his findings. The tester, similarly, needs to feel prepared to communicate the bugs he finds effectively. There's no need to pass judgment on the developer, but instead to help the developer by giving him data and supporting him with follow-up tests when the bug has been fixed.
Similarly, the developer needs to treat the tester with respect and not become defensive. If it appears the tester is focusing on the wrong area of code, the developer should explain this, not in a condescending way, but in a way that will help both partners get on the same page. When the tester finds bugs, the developer should show appreciation, and maybe work together with the tester to understand how he was able to uncover the bugs. If there's an area that is particularly prone to problems, the developer and tester might work together to create an automated regression test suite.
Operate as a unified team
Developers and testers must learn to operate together as a team, regardless of their organizational structure or methodology. This can be done using respectful communication and working together to achieve the overall goal of creating a high quality application.

Source: SearchSoftwareQuality.com

---

Monday, November 8, 2010

Selenium - TestNG vs JUnit

Selenium - TestNG vs JUnit


Selenium programmers require one of the above mentioned frameworks to create tests. This post explain the differences and implementation of these frameworks.


TestNG Documentation
TestNG Eclipse
JUnit Documentation


JUnit 4 and TestNG are both very popular unit test framework in Java. Both frameworks look very similar in functionality. Which one is better? Which unit test framework should i use in Selenium project?
Here is the feature comparison between JUnit 4 and TestNG.

1. Annotation Support

The annotation supports are implemented in both JUnit 4 and TestNG look similar.
FeatureJUnit 4TestNG
test annotation@Test@Test
run before all tests in this suite have run@BeforeSuite
run after all tests in this suite have run@AfterSuite
run before the test@BeforeTest
run after the test@AfterTest
run before the first test method that belongs to any of these groups is invoked@BeforeGroups
run after the last test method that belongs to any of these groups is invoked@AfterGroups
run before the first test method in the current class is invoked@BeforeClass@BeforeClass
run after all the test methods in the current class have been run@AfterClass@AfterClass
run before each test method@Before@BeforeMethod
run after each test method@After@AfterMethod
ignore test@ignore@Test(enbale=false)
expected exception@Test(expected = ArithmeticException.class)@Test(expectedExceptions = ArithmeticException.class)
timeout@Test(timeout = 1000)@Test(timeout = 1000)
The main annotation differences between JUnit4 and TestNG are
1. In JUnit 4, we have to declare “@BeforeClass” and “@AfterClass” method as static method. TestNG is more flexible in method declaration, it does not have this constraints.
2. 3 additional setUp/tearDown level: suite and group (@Before/AfterSuite, @Before/AfterTest, @Before/AfterGroup). See more detail here.
JUnit 4
    @BeforeClass
    public static void oneTimeSetUp() {
        // one-time initialization code   
    	System.out.println("@BeforeClass - oneTimeSetUp");
    }
TestNG
    @BeforeClass
    public void oneTimeSetUp() {
        // one-time initialization code   
    	System.out.println("@BeforeClass - oneTimeSetUp");
}
In JUnit 4, the annotation naming convention is a bit confusing, e.g “Before”, “After” and “Expected”, we do not really understand what is “Before” and “After” do, and what we “Expected” from test method? TestNG is easier to understand, it using “BeforeMethod”, “AfterMethod” and “ExpectedException” instead.

2. Exception Test

The “exception testing” means what exception throw from the unit test, this feature are implemented in both JUnit 4 and TestNG.
JUnit 4
      @Test(expected = ArithmeticException.class)  
	public void divisionWithException() {  
	  int i = 1/0;
	}
TestNG
      @Test(expectedExceptions = ArithmeticException.class)  
	public void divisionWithException() {  
	  int i = 1/0;
	}

3. Ignore Test

The “Ignored” means whether it should ignore the unit test, this feature are implemented in both JUnit 4 and TestNG .
JUnit 4
        @Ignore("Not Ready to Run")  
	@Test
	public void divisionWithException() {  
	  System.out.println("Method is not ready yet");
	}
TestNG
	@Test(enabled=false)
	public void divisionWithException() {  
	  System.out.println("Method is not ready yet");
	}

4. Time Test

The “Time Test” means if an unit test takes longer than the specified number of milliseconds to run, the test will terminated and mark as fails, this feature is implemented in both JUnit 4 and TestNG .
JUnit 4
        @Test(timeout = 1000)  
	public void infinity() {  
		while (true);  
	}
TestNG
	@Test(timeOut = 1000)  
	public void infinity() {  
		while (true);  
	}

5. Suite Test

The “Suite Test” means bundle a few unit test and run it together. This feature is implemented in both JUnit 4 and TestNG. However both are using very different method to implement it.
JUnit 4
The “@RunWith” and “@Suite” are use to run the suite test. The below class means both unit test “JunitTest1” and “JunitTest2” run together after JunitTest5 executed. All the declaration is define inside the class.
@RunWith(Suite.class)
@Suite.SuiteClasses({
        JunitTest1.class,
        JunitTest2.class
})
public class JunitTest5 {
}
TestNG
XML file is use to run the suite test. The below XML file means both unit test “TestNGTest1” and “TestNGTest2” will run it together.

 name="My test suite">
   name="testing">
    >
        name="com.fsecure.demo.testng.TestNGTest1" />
        name="com.fsecure.demo.testng.TestNGTest2" />
    >
  >
>
TestNG can do more than bundle class testing, it can bundle method testing as well. With TestNG unique “Grouping” concept, every method is tie to a group, it can categorize tests according to features. For example,
Here is a class with four methods, three groups (method1, method2 and method3)
        @Test(groups="method1")
	public void testingMethod1() {  
	  System.out.println("Method - testingMethod1()");
	}  
 
	@Test(groups="method2")
	public void testingMethod2() {  
		System.out.println("Method - testingMethod2()");
	}  
 
	@Test(groups="method1")
	public void testingMethod1_1() {  
		System.out.println("Method - testingMethod1_1()");
	}  
 
	@Test(groups="method4")
	public void testingMethod4() {  
		System.out.println("Method - testingMethod4()");
	}
With the following XML file, we can execute the unit test with group “method1” only.

 name="My test suite">
   name="testing">
  	>
      >
         name="method1"/>
      >
    >
    >
        name="com.fsecure.demo.testng.TestNGTest5_2_0" />
    >
  >
>
With “Grouping” test concept, the integration test possibility is unlimited. For example, we can only test the “DatabaseFuntion” group from all of the unit test classes.

6. Parameterized Test

The “Parameterized Test” means vary parameter value for unit test. This feature is implemented in both JUnit 4 and TestNG. However both are using very different method to implement it.
JUnit 4
The “@RunWith” and “@Parameter” is use to provide parameter value for unit test, @Parameters have to return List[], and the parameter will pass into class constructor as argument.
@RunWith(value = Parameterized.class)
public class JunitTest6 {
 
	 private int number;
 
	 public JunitTest6(int number) {
	    this.number = number;
	 }
 
	 @Parameters
	 public static Collection<Object[]> data() {
	   Object[][] data = new Object[][] { { 1 }, { 2 }, { 3 }, { 4 } };
	   return Arrays.asList(data);
	 }
 
	 @Test
	 public void pushTest() {
	   System.out.println("Parameterized Number is : " + number);
	 }
}
It has many limitations here; we have to follow the “JUnit” way to declare the parameter, and the parameter has to pass into constructor in order to initialize the class member as parameter value for testing. The return type of parameter class is “List []”, data has been limited to String or a primitive value for testing.
TestNG
XML file or “@DataProvider” is use to provide vary parameter for testing.
XML file for parameterized test.
Only “@Parameters” declares in method which needs parameter for testing, the parametric data will provide in TestNG’s XML configuration files. By doing this, we can reuse a single test case with different data sets and even get different results. In addition, even end user, QA or QE can provide their own data in XML file for testing.
Unit Test
      public class TestNGTest6_1_0 {
 
	   @Test
	   @Parameters(value="number")
	   public void parameterIntTest(int number) {
	      System.out.println("Parameterized Number is : " + number);
	   }
 
      }
XML File

 name="My test suite">
   name="testing">
 
     name="number" value="2"/> 	
 
    >
        name="com.fsecure.demo.testng.TestNGTest6_0" />
    >
  >
>
@DataProvider for parameterized test.
While pulling data values into an XML file can be quite handy, tests occasionally require complex types, which can’t be represented as a String or a primitive value. TestNG handles this scenario with its @DataProvider annotation, which facilitates the mapping of complex parameter types to a test method.
@DataProvider for Vector, String or Integer as parameter
        @Test(dataProvider = "Data-Provider-Function")
	public void parameterIntTest(Class clzz, String[] number) {
	   System.out.println("Parameterized Number is : " + number[0]);
	   System.out.println("Parameterized Number is : " + number[1]);
	}
 
	//This function will provide the patameter data
	@DataProvider(name = "Data-Provider-Function")
	public Object[][] parameterIntTestProvider() {
		return new Object[][]{
				   {Vector.class, new String[] {"java.util.AbstractList", 
"java.util.AbstractCollection"}},
				   {String.class, new String[] {"1", "2"}},
				   {Integer.class, new String[] {"1", "2"}}
				  };
	}
@DataProvider for object as parameter
P.S “TestNGTest6_3_0” is an simple object with just get set method for demo.
        @Test(dataProvider = "Data-Provider-Function")
	public void parameterIntTest(TestNGTest6_3_0 clzz) {
	   System.out.println("Parameterized Number is : " + clzz.getMsg());
	   System.out.println("Parameterized Number is : " + clzz.getNumber());
	}
 
	//This function will provide the patameter data
	@DataProvider(name = "Data-Provider-Function")
	public Object[][] parameterIntTestProvider() {
 
		TestNGTest6_3_0 obj = new TestNGTest6_3_0();
		obj.setMsg("Hello");
		obj.setNumber(123);
 
		return new Object[][]{
				   {obj}
		};
	}
TestNG’s parameterized test is very user friendly and flexible (either in XML file or inside the class). It can support many complex data type as parameter value and the possibility is unlimited. As example above, we even can pass in our own object (TestNGTest6_3_0) for parameterized test

7. Dependency Test

The “Parameterized Test” means methods are test base on dependency, which will execute before a desired method. If the dependent method fails, then all subsequent tests will be skipped, not marked as failed.
JUnit 4
JUnit framework is focus on test isolation; it did not support this feature at the moment.
TestNG
It use “dependOnMethods “ to implement the dependency testing as following
        @Test
	public void method1() {
	   System.out.println("This is method 1");
	}
 
	@Test(dependsOnMethods={"method1"})
	public void method2() {
		System.out.println("This is method 2");
	}
The “method2()” will execute only if “method1()” is run successfully, else “method2()” will skip the test.


Conclusion:
After going thought all the features comparison, I suggest to use TestNG as core framework for Selenium project, because TestNG is more advance in parameterize testing, dependency testing, suite testing (Grouping concept), running test in multi threads and generate html reports. TestNG is meant for high-level testing and complex integration test. Its flexibility is especially useful with large test suites. In addition, TestNG also cover the entire core JUnit4 functionality. It’s just no reason for me to use JUnit anymore.
Source: mkyong

----