Friday, 15 August 2014

Data driven testing in TestNG (Using @DataProvider annotaion)





-> @DataProvider annotations in TestNG is important for data driven framework in selenium.

-> @DataProvider Annotation of testng framework provides us a facility of storing and preparing data set In method.

-> Task for @DataProvider Annotation is supplying data for test method. That means we can configure data with in the @DataProvider annotations and use those data inside the @Test methods.

-> @dataprovider method should return an Object[][] with data.

-> we have to create two dimensional array in @DataProvider annotation data to stored the data.



Example:


Bellow given example will retrieve userid and password one by one from @DataProvider annotated method and will feed them In LogIn_Test(String Usedid, String Pass) one by one. Run this example In your eclipse and observe result.



public class Sample_Login {

 WebDriver driver = new FirefoxDriver();


 @BeforeTest
    public void setup() throws Exception {
         driver.manage().window().maximize();
         driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
         driver.get("http://only-testing-blog.blogspot.in/2014/05/login.html");
    }


  @AfterTest
 public void tearDown() throws Exception {
   driver.quit();
     }


 //This method will return two dimensional array.
 //This method behaves as data provider for LogIn_Test method.

 @DataProvider

 public Object[][] LoginCredentials(){

  //Created two dimensional array with 4 rows and 2 columns.
  //4 rows represents test has to run 4 times.
  //2 columns represents 2 data parameters.

 Object[][] Cred = new Object[4][2];

  Cred[0][0] = "UserId1";
  Cred[0][1] = "Pass1";

  Cred[1][0] = "UserId2";
  Cred[1][1] = "Pass2";

  Cred[2][0] = "UserId3";
  Cred[2][1] = "Pass3";

  Cred[3][0] = "UserId4";
  Cred[3][1] = "Pass4";
  return Cred; //Returned Cred
 }



 //Give data provider method name as data provider.
 //Passed 2 string parameters as LoginCredentials() returns 2 parameters In object.

 @Test(dataProvider="LoginCredentials")

 public void LogIn_Test(String Usedid, String Pass){
   driver.findElement(By.xpath("//input[@name='userid']")).clear();
   driver.findElement(By.xpath("//input[@name='pswrd']")).clear();
   driver.findElement(By.xpath("//input[@name='userid']")).sendKeys(Usedid);
   driver.findElement(By.xpath("//input[@name='pswrd']")).sendKeys(Pass);
   driver.findElement(By.xpath("//input[@value='Login']")).click();
   String alrt = driver.switchTo().alert().getText();
   driver.switchTo().alert().accept();
   System.out.println(alrt);
  }
}




testng.xml file to run this example Is as bellow.


<suite name="Simple Suite">
 <test name="Simple Skip Test">
  <classes>
   <class name = "Testng_Pack.Sample_Login"/>
  </classes>
 </test>
</suite>




After run the above code, the user id and password entered one by one in above URL.

Selenium WebDriver Parallel Tests Execution Using TestNG - @Parameters




-> Browser compatibility testing Is most Important thing for any web application and generally you have to perform browser compatibility testing before 1 or 2 days of final release of application. In such a sort time period, you have to verify each Important functionality In every browsers suggested by client.


-> If you will go for running your all webdriver tests In each browsers one by one then It will take too much time to complete your test and you may not complete It before release.

-> In such situation, Running your tests In all required browsers at same time will helps you to save your time efforts.

-> The above situation solved in selenium by using @Parameters annotation in TestNG framework.



Parallelism In TestNG


We can configure our TestNG.xml file in such a way to run our test suite or tests or methods in seperate browsers Is known as parallelism In TestNG.


ParellelTestng.java


package TestNG_Package;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

public class TestNG_Test1 {

 private  WebDriver driver1=null;

  @BeforeClass
  @Parameters ({"browser"})

  public void setup(String browser)
 {
   if (browser.equals("FFX"))
  {
     System.out.println("Test Starts Running In Firefox Browser.");
     driver1 = new FirefoxDriver(); 
    }
  else if (browser.equals("CRM"))
  {
     System.out.println("Test Starts Running In Google chrome.");
     System.setProperty("webdriver.chrome.driver",  "D:\\chromedriver_win32_2.3\\chromedriver.exe");
     driver1 = new ChromeDriver(); 
   }
   driver1.manage().window().maximize();
   driver1.get("http://only-testing-blog.blogspot.in/2014/05/login.html");
  }


 @AfterClass
 public void closebrowser()
 {
    driver1.quit();
 }


 @Test
 public void MethodOne() {

  String a= "Selenium";
  if(a.equals("Selenium")
   throw new SkipException("Skipped");

  String title = driver1.getTitle();
  System.out.println("title"+title);   
 }



 @Test
 public void MethodTwo() {
  String title = driver1.getTitle();
  System.out.println("title"+title);   
 }


}




testng.xml

<suite name="webDriver" parallel="tests">

 <test name="Test In FireFox" >
    <parameter name="browser" value="FFX" />
    <classes>
      <class name="Testng_Pack.Test_Parallel" />
    </classes>
  </test>

   <test name="Test In Google Chrome" >
    <parameter name="browser" value="CRM"></parameter>
    <classes>
      <class name="Testng_Pack.Test_Parallel"></class>
    </classes>
  </test>

</suite>




From above example we can run same test in both Chrome and FireFox at same time.

From above Testng.xml file

-> parallel="tests" which inside <suite> tag will instruct TestNG to consider method of each <test> tag as seperate Thread. that Means If you wants to run your test In 2 different browsers then you need to create two <test> blocks for each browser Inside testng.xml file.

-> Inside each <test> tag block, define one more tag "parameter" with same name(In both <test> block) but with different values.Its used to pass in ParellelTestng.java method.



From ParellelTestng.java

-> Here we are used @Parameters annotation to pass parameter in method.Values of this parameter will be feed by testng.xml file.

-> If condition will check that value to decide which driver to use for test. This way, example testng.xml file will feed two values(FFX and CRM) In parameter so It will open Firefox and Google chrome browsers and run test In both browsers

How To Skip WebDriver Test In TestNG





We can skip the execution from perticular test by using throw new SkipException() exception. THis is TestNG exception.

Sometimes you need to check some condition like If some condition match then skip test else perform some action In your webdriver test. In this kind of situation, you can use SkipException() exception.


Consider below example




package TestNG_Package;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

public class TestNG_Test1 {
WebDriver driver1=new FirefoxDriver();
@BeforeMethod
public void OpenBrowser(){
driver1.get("http://google.com");
driver1.manage().window().maximize();
}
@AfterMethod
public void CloseBrowser(){
driver1.quit();
}
@Test
public void MethodOne() {

String a= "Selenium";
if(a.equals("Selenium")
throw new SkipException("Skipped");

String title = driver1.getTitle();
System.out.println("title"+title);   
}



@Test
public void MethodTwo() {
String title = driver1.getTitle();
System.out.println("title"+title);   
}


}



o/p

MethodOne Skipped due to SkipException()
MethodTwo executed


From above example if execution throw SkipExeption() means the rest of the commands inside the method wont get executed. Its skipped from current method and control goes to next method.

Include/Exclude Selenium WebDriver Test Package From Test Suite Using testng.xml




We can include or exclude selenium webdriver from test suite using below steps


1) Create new package and classes as below

TestNGOnePack(package) -> BaseClassOne.java, ClassOne.java, ClassTwo.java
TestNGTwoPack(package) -> ClassOne.java, ClassTwo.java
TestNGThreePack(package) -> ClassOne.java, ClassTwo.java


2) Include perticular package from test suite


<suite name="Suite One">
  <test name="Test One" >
     <packages>
        <package name=".*">
           <include name="TestNGOnePack" > </include>
        </package>
     </packages>
  </test>
</suite>


We can execute only "TestNGOnePack", "TestNGThreePack" package from this execution. We exclude "TestNGTwoPack" package from execution.


3) Exclude Perticular package from test suite execution



<suite name="Suite One">
  <test name="Test One" >
     <packages>
        <package name=".*">
           <exclude name="TestNGOnePack" > </exclude>
        </package>
     </packages>
  </test>
</suite>

We can execute only  "TestNGTwoPack","TestNGThreePack" package from this execution. We exclude "TestNGOnePack" package from execution.So its not get execute.

Include/Exclude Only Selected Test Methods from class Test Suite Using testng.xml





Its possbile we can include or exclude selected test method from any class.


1) Create new package and classes as below

TestNGOnePack(package) -> TestNG_Test1.java

2) And BaseClassOne.java have before methods

TestMethod1(),TestMethod2(),TestMethod3()



3) Include test method from class for execution


<suite name="TestNG_Suite">
<test name="TestNG_Test">
<classes>
<class name="TestNGOnePack.TestNG_Test1"></class>
<methods>
<include name="TestMethod1"> </include>
<include name="TestMethod2"> </include>
</methods>
</classes>
</test>
</suite>



From above example, we execute only TestMethod1 and TestMethod2 in execution. But the TestMethod3 is not executed.




4) Exclude Test Method from class for execution.


<suite name="TestNG_Suite">
<test name="TestNG_Test">
<classes>
<class name="TestNGOnePack.TestNG_Test1"></class>
<methods>
<exclude name="TestMethod1"> </exclude>   
</methods>
</classes>
</test>
</suite>



From above example, we execute only TestMethod2(),TestMethod3() in execution. But TestMethod1() is exclude from execution. So its not executed.

Configure testng.xml In Eclipse For Selenium WebDriver To Run All Or Specific Package



TestNG is very useful and powerful framework for selenium webdriver. We need to configure our tests based on our requirements or test scenarios.


Create new package and classes as below


TestNGOnePack(package) -> BaseClassOne.java, ClassOne.java, ClassTwo.java
TestNGTwoPack(package) -> ClassOne.java, ClassTwo.java
TestNGThreePack(package) -> ClassOne.java, ClassTwo.java



Configure testng.xml to run selected packages from all packages of webdriver project in single test suite


From three packages, I wants to run only two packages -> "TestNGTwoPack" and "TestNGThreePack". For that we need to configure testng.xml as bellow.

<suite name="Suite One">
 <test name="Test One" >
  <packages>
   <package name="TestNGTwoPack" />
   <package name="TestNGThreePack" />
  </packages>
 </test>
</suite>


In above example <packages> tag used to describe group of packagesand  is used to add specific package in our test suite.

So when you run above testng.xml file, It will run only targeted two packages(TestNGTwoPack, TestNGThreePack). Other (TestNGOnePack)package(s) will be excluded from execution.


Configure testng.xml to run all packages of project in single test suite

If you wants to run all packages of your project, you can configure your testng.xml using wildcard(.*) with package tag as bellow.

<suite name="Suite One">
 <test name="Test One" >
  <packages>
   <package name=".*" />  
  </packages>
 </test>
</suite>

Configure testng.xml In Eclipse For Creating Web Driver test using classes from different packages.



For example we create new packages and classes using below steps,

Step 1. Create package = "TestNGOnePack" with classes = BaseClassOne.java, ClassOne.java and ClassTwo.java

Step 2. Create package = "TestNGTwoPack" under same project and add ClassOne.java and ClassTwo.java files

Step 3. Create package = "TestNGThreePack" under same project and add ClassOne.java and ClassTwo.java file



Here i dont want to execut all classes from all packages. I need some selected classes from selected packages. like like TestNGOnePack.ClassOne, TestNGTwoPack.ClassTwo, TestNGThreePack.ClassOne and TestNGThreePack.ClassTwo


Here we need to configure testng.xml file as below

<suite name="Suite One">
 <test name="Test One" >
  <classes>
   <class name="TestNGOnePack.ClassOne" />
   <class name="TestNGTwoPack.ClassTwo" />
   <class name="TestNGThreePack.ClassOne" />
   <class name="TestNGThreePack.ClassTwo" /> 
  </classes>
 </test>
</suite>


This way we can configure our test suite using only specific class from different packages