Tuesday 29 January 2013

Selenium GRID with WebDriver

Selenium Grid is a tool that dramatically speeds up functional testing of web-apps by leveraging your existing computing infrastructure. It allows you to easily run multiple tests in parallel, on multiple machines, in an heterogeneous environment.

Stop waiting hours to get the results of your web acceptance builds! Selenium Grid transparently distribute your tests on multiple machines so that you can run your tests in parallel, cutting down the time required for running in-browser test suites. This will dramatically speeds up in-browser web testing, giving you quick and accurate feedback you can rely on to improve your web application.


How to Configure Selenium GRID

1) Download latest Selenium-server-standalone-2.25.0.jar
2) Download TestNG (should have TestNG framework)
3) Download ChromeDriver.exe

Test Script

package testNG;

import java.net.MalformedURLException;
import java.net.URL;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverBackedSelenium;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

import com.thoughtworks.selenium.Selenium;

import junit.framework.Assert;

public class Google {

 private Selenium selenium;

 @Parameters({"browser","port"})

 @BeforeClass
 public void beforeClass(String browser,String port){
  DesiredCapabilities capability= new DesiredCapabilities();
  capability.setBrowserName(browser);
  try {
   WebDriver driver= new RemoteWebDriver(new URL("http://localhost:".concat(port).concat("/wd/hub")), capability);
   selenium = new WebDriverBackedSelenium(driver, "http://www.google.com");
  } catch (MalformedURLException e) {
    
   e.printStackTrace();
  }
 }
  
 @Test
 public void search() {
  selenium.open("/");
  selenium.type("id=lst-ib", "testing");
  selenium.click("//input[@value='Google Search']");
  }

 @AfterClass
 public void afterClass(){
  selenium.stop();
 }
  
}

Create the TestNG.xml file by copying the below code: 

<?xml version="1.0" encoding="UTF-8"?>
<suite name="Suite" parallel="tests"
    thread-count="5">

    <test name="Selenium TestNG - 1">
        <parameter name="browser" value="firefox" />
        <parameter name="port" value="4444" />
        <classes>
            <class name="testNG.Google" />
        </classes>
    </test>
    <test name="Selenium TestNG - 2">
        <parameter name="browser" value="chrome" />
        <parameter name="port" value="4444" />
        <classes>
            <class name="testNG.Google" />
        </classes>
    </test>

</suite>

Now run the Test Suite by right clicking the TestNG.xml file from eclipse

Just Before running the script you should run Selenium-Grid server

Selenium-Grid server

For Hub:
java -jar selenium-server-standalone-2.25.0.jar -role hub


For a firefox based node:
java -jar selenium-server-standalone-2.25.0.jar -role webdriver -hub http://localhost:4444/grid/register -port 5556 -browser browserName=firefox

For Google-Chrome based node:

java -Dwebdriver.chrome.driver="C:\.......\chromedriver.exe" -jar selenium-server-standalone-2.25.0.jar -role webdriver -hub http://localhost:4444/grid/register -port 5555 -browser browserName=chrome

Monday 21 January 2013

XSLT- Generate Interactive reports on TestNG+ANT

XSLT stands for XML (Extensible Markup Language) Stylesheet Language for Transformations.
XSLT gives interactive(user friendly) reports with "Pie Chart"; but only on TestNG framework. It is better compared to ReportNG and ordinary TestNG reports. It uses the pure XSL for report generation and Saxon as an XSL2.0 implementation.

XSLT = XSL Transformations

Steps to Generate testng-xslt report:

1. Download testng-xslt.zip
2. Unzip and copy the testng-results.xsl from the testng-xslt folder(testng-xslt-1.1\src\main\resources) to your own project folder.
3. Now copy the saxon library from (testng-xslt-1.1\lib\saxon-8.7.jar) to your project lib folder.
4. Make sure Guice-x.x.jar is available in the build path. [As shown in my GIT https://github.com/prashanth-sams/Xslt_Ant_Testng_Example/tree/master/lib]
5. Modify your build.xml of ant and add the following target to it.


<?xml version="1.0" encoding="UTF-8"?>
        <project name="automation" default="Run" basedir=".">
<property name="src.dir" value="${basedir}/src"/>
<property name="build.dir" value="${basedir}/build"/>
<property name="testng_output.dir" value="${basedir}/testng_output"/>

<!-- get class path, used for build -->
<property name="lib.dir" value="${basedir}/lib"/>
<path id="classpath">
        <fileset dir="${lib.dir}" includes="*.jar"/>
<pathelement location="build"/>
       </path>

<!-- create build folder, testng_output folder and remove old log file -->
<target name="init">
<delete dir="${build.dir}"/>
<delete dir="${testng_output}"/>
<delete dir="${basedir}/testng-xslt"/>
<mkdir dir="${build.dir}"/>
<mkdir dir="${basedir}/testng-xslt"/>
                <mkdir dir="${testng_output.dir}"/>
   
</target>

<!-- build all java file to class binary -->
<target name="compile" depends="init">
   <javac srcdir="${basedir}/src" destdir="${basedir}/build" classpathref="classpath" includeantruntime="false">
   <compilerarg value="-Xlint:unchecked"/>
   </javac> 
</target>

<!-- Config for testng -->
<taskdef name="testng" classname="org.testng.TestNGAntTask">
   <classpath>
    <pathelement location="lib/testng-6.8beta.jar"/>
   </classpath>
  </taskdef>
 

<!-- execute testng after compile, then generate report -->
<target name ="Run" depends="compile">

<!-- config testng -->
   <testng outputdir="${testng_output.dir}" classpathref="classpath" useDefaultListeners="true">

    <!-- execute testcase follow testng.xml -->
    <xmlfileset dir="." includes="testng.xml"/>
   
    <!-- generate report title -->
    <sysproperty key="org.uncommons.reportng.title" value="Test Automation"/>
    <sysproperty key="org.uncommons.reportng.escape-output" value="false"/>
   </testng>
</target>
  
<target name="xslt" depends="Run">
                 
   <xslt in="${basedir}/testng_output/testng-results.xml" style="${basedir}/testng-results.xsl" out="${basedir}/testng-xslt/index.html" processor="SaxonLiaison">
                        
            <param expression="${basedir}/testng-xslt/" name="testNgXslt.outputDir" />

            <param expression="true" name="testNgXslt.sortTestCaseLinks" />

            <param expression="FAIL,SKIP,PASS,CONF,BY_CLASS" name="testNgXslt.testDetailsFilter" />

            <param expression="true" name="testNgXslt.showRuntimeTotals" />

            <classpath refid="master-classpath">
            </classpath>
        </xslt>
    </target>

<property name="LIB" value="${basedir}/lib" />
<property name="BIN" value="${basedir}/bin" />
<path id="master-classpath">
<pathelement location="${BIN}" />
      <fileset dir="${LIB}">
         <include name="**/*.jar" />
      </fileset>
</path>

</project>


5. Create TestNG.xml file in your project with the following script for TestNG execution.

<?xml version="1.0" encoding="UTF-8"?>
<suite name="Suite" parallel="false">
  <test name="Test">
    <classes>
      <class name="package.classname"/>
    </classes>
  </test> <!-- Test -->
</suite> <!-- Suite -->

6. Now, try to run the command.

ant xslt



Thursday 10 January 2013

ReportNG - HTML/XML Reporting Plug-in for TestNG


ReportNG is a simple HTML reporting plug-in for the TestNG unit-testing framework. It is intended as a replacement for the default TestNG HTML report. The default report is comprehensive but is not so easy to understand at-a-glance. ReportNG provides a simple, colour-coded view of the test results.

Disable the Default Listeners first

Project (right-click) > Properties > TestNG > Tick “Disable default listeners” > Apply > ok

The reportng-1.1.3.jar and velocity-dep-1.4.jar files must be included in the classpath to run the tests.

Download ReportNG (jar) files 
 Download reportng.jar
 Download velocity.jar

Check your project .classpath after build configure;

<classpathentry kind="lib" path="lib/velocity-dep-1.x.jar"/>
<classpathentry kind="lib" path="lib/testng-6.x.jar"/>
<classpathentry kind="lib" path="lib/reportng-1.1.x.jar"/>

Create the xml file by copying the below code: 

Right-click your Project/Class file > TestNG > "Convert to TestNG" > Edit the xml code by adding LISTENERS given below > Finish

<?xml version="1.0" encoding="UTF-8"?>
<suite name="Suite" parallel="false">
  <listeners>
      <listener class-name="org.uncommons.reportng.HTMLReporter"/>
      <listener class-name="org.uncommons.reportng.JUnitXMLReporter"/>
  </listeners>
  <test name="Test">
    <classes>
      <class name="package.classname"/>
    </classes>
  </test> <!-- Test -->
</suite> <!-- Suite -->

Now run the TestNG framework by right clicking the .xml file from eclipse

Sample Report1 ReportNG
Sample Report2 ReportNG

Wednesday 9 January 2013

Track WebPage Load Time | Selenium

long start = System.currentTimeMillis();
driver.get("http://www.website.com");    

// Locate an element [code here]

long finish = System.currentTimeMillis();
long TotalTime = finish - start;
System.out.println("Total Time for page load - "+TotalTime); 


#PYTHON
def setUp(self):
        self.startTime = time.time()

def tearDown(self):
        t = time.time() - self.startTime
        print "%s: %.3f" % (self.id(), t)
        self.driver.quit

Thursday 3 January 2013

JUnit4 - Parameterization

Junit 4 has introduced a new feature called Parameterization.  Parameterized tests allow the developers to run the same test over and over again using different values. There are 5 different steps that you need to followup in-order to create Parameterized tests.
  1. Annotating the test class with @RunWith(Parameterized.class)
  2. Create a public static method annotated with @Parameters that returns a Collection of Objects (as Array) as test data set.
  3. Create a public constructor that takes in what is equivalent to one "row" of test data.
  4. Create an instance variable for each "column" of test data.
  5. Create your tests case(s) using the instance variables as the source of the test data.
The test case will be invoked once per each row of data. Let's see Parameterized tests in action.

Exercise |1|

1| Create a java class; say, Calculator.java

public class Calculator {
public int add(int x, int y){
return x+y;
}
}

Create Parameterized Test Class

2| Create a java test class say, Easy.java

import java.util.Arrays;
import java.util.Collection;
import junit.framework.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

import org.junit.runners.Parameterized.Parameters;

@RunWith(Parameterized.class)
public class Easy {

private int Expected;
private int Firstval;
private int Secondval;
public Calculator cal;

@Before
public void setUp(){
cal = new Calculator();
}

public Easy(int Expected, int Firstval, int Secondval){
this.Expected = Expected;
this.Firstval = Firstval;
this.Secondval = Secondval;
}

@Parameters
public static Collection<Object[]> storedtestdata(){
return Arrays.asList(new Object[][]{
{5,3,2}, // pass
{8,4,4}, // pass
{6,1,4}  // fail
});
}

@Test
public void Test01(){
Assert.assertEquals(Expected, cal.add(Firstval, Secondval));
}
}

Create Test Runner Class [Optional and not mandatory]

3| Create a class, TestRunner.java under the same package in-order to execute Test case(s)

import org.junit.runner.JUnitCore;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;

public class TestRunner {
   public static void main(String[] args) {
      Result result = JUnitCore.runClasses(Easy.class);
      for (Failure failure : result.getFailures()) {
         System.out.println(failure.toString());
      }
      System.out.println(result.wasSuccessful());
   }
}  
Verify the output:

Test01[2](pack.Easy): expected:<6> but was:<5>
false


Exercise |2|

1| Create a java class; say, PrimeNumberChecker.java

public class PrimeNumberChecker {
   public Boolean validate(final Integer primeNumber) {
      for (int i = 2; i < (primeNumber / 2); i++) {
         if (primeNumber % i == 0) {
            return false;
         }
      }
      return true;
   }
}

Create Parameterized Test Class

2| Create a java class; say, PrimeNumberCheckerTest.java

@RunWith(Parameterized.class)
public class PrimeNumberCheckerTest {
   private Integer inputNumber;
   private Boolean expectedResult;
   private PrimeNumberChecker primeNumberChecker;

   @Before
   public void initialize() {
      primeNumberChecker = new PrimeNumberChecker();
   }

   // Each parameter should be placed as an argument here
   // Every time runner triggers, it will pass the arguments
   // from parameters we defined in primeNumbers() method
   public PrimeNumberCheckerTest(Integer inputNumber, 
      Boolean expectedResult) {
      this.inputNumber = inputNumber;
      this.expectedResult = expectedResult;
   }

   @Parameterized.Parameters
   public static Collection primeNumbers() {
      return Arrays.asList(new Object[][] {
         { 2, true },
         { 6, false },
         { 19, true },
         { 22, false },
         { 23, true }
      });
   }

   // This test will run 4 times since we have 5 parameters defined
   @Test
   public void testPrimeNumberChecker() {
      System.out.println("Parameterized Number is : " + inputNumber);
      assertEquals(expectedResult, 
      primeNumberChecker.validate(inputNumber));
   }
}
Verify the output:

Parameterized Number is : 2
Parameterized Number is : 6
Parameterized Number is : 19
Parameterized Number is : 22
Parameterized Number is : 23
true

Selenium - Generate HTML Reports using JUnit+ANT


Apache Ant is an open source build tool. A build tool can be used to compile the source code, creating the build artifacts such as JAR, WAR, and EAR files.  Some of the other usage of ANT is to run unit tests, do the application deployment on containers such as JBoss, Tomcat, WebSphere, WebLogic, GlassFish, etc, and to run Automated Selenium Tests.

In this example, we will demonstrate how to Generate HTML Reports using ANT. Let's follow the given steps:
Step 1: Download Apache Ant
Download Apache Ant

OSArchive name
Windowsapache-ant-1.8.4-bin.zip
Linuxapache-ant-1.8.4-bin.tar.gz
Macapache-ant-1.8.4-bin.tar.gz
Step 2: Set Ant Environment

Set the ANT_HOME environment variable to point to the base directory location where ANT libraries is stored on your machine. For example, We've stored Ant libraries in apache-ant-1.8.4 folder on various Operating Systems as follows.

OSOutput
WindowsSet the environment variable ANT_HOME to C:\Program Files\Apache Software Foundation\apache-ant-1.8.4
Linuxexport ANT_HOME=/usr/local/\apache-ant-1.8.4
Macexport ANT_HOME=/Library/\apache-ant-1.8.4
Append Ant compiler location to System Path is as follows for different OS:
OSOutput
WindowsAppend the string ;%ANT_HOME\bin to the end of the system variable, Path.
Linuxexport PATH=$PATH:$ANT_HOME/bin/
Macnot required
Step 3: Download Junit Archive

Download JUnit Archive
OSArchive name
Windowsjunit4.10.jar
Linuxjunit4.10.jar
Macjunit4.10.jar

Let us create a new project in Eclipse and write a build.xml file to execute the Java files in this project 

1) Create a new project – JavaProject
2) Create a new package (under src) – seleniumtest
3) Under this package, create new Java class – AntTest.java
4) Record a Selenium Test and export in JUnit 4 format as below

package seleniumtest;

import com.thoughtworks.selenium.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.server.SeleniumServer;

public class AntTest extends SeleneseTestCase{
private static SeleniumServer seleniumServer;
@Before
public void setUp() throws Exception {
selenium = new DefaultSelenium("localhost", 4444, "*chrome", "http://www.google.co.in/");
        seleniumServer = new SeleniumServer();
        seleniumServer.start();
selenium.start();
}

@Test
public void testGoogleSearch() throws Exception {
selenium.open("/");
selenium.click("link=Advanced search");
selenium.waitForPageToLoad("30000");
selenium.type("as_q", "selftechy, selenium");
selenium.click("//input[@value='Advanced Search']");
selenium.waitForPageToLoad("30000");
}

@After
public void tearDown() throws Exception {
selenium.stop();
seleniumServer.stop();
}

}

Create ANT Build.xml under JavaProject

<?xml version="1.0" encoding="UTF-8"?>
<project name="test" default="exec" basedir=".">

<property name="src" value="./src" />
<property name="lib" value="./lib" />
<property name="bin" value="./bin" />
<property name="report" value="./report" />
<path id="test.classpath">
<pathelement location="${bin}" />
<fileset dir="${lib}">
<include name="**/*.jar" />
</fileset>
</path>

<target name="init">
<delete dir="${bin}" />
<mkdir dir="${bin}" />
</target>

<target name="compile" depends="init">
<javac source="1.6" srcdir="${src}" fork="true" destdir="${bin}" includeantruntime="false">
<classpath>
<pathelement path="${bin}">
</pathelement>
<fileset dir="${lib}">
<include name="**/*.jar" />
</fileset>
</classpath>
</javac>
</target>

<target name="exec" depends="compile">
<delete dir="${report}" />
<mkdir dir="${report}" />
<mkdir dir="${report}/xml" />
<junit printsummary="yes" haltonfailure="no">
<classpath>
<pathelement location="${bin}" />
<fileset dir="${lib}">
<include name="**/*.jar" />
</fileset>
</classpath>

<test name="seleniumtest.AntTest" haltonfailure="no" todir="${report}/xml" outfile="TEST-result">
<formatter type="xml" />
</test>
</junit>
<junitreport todir="${report}">
<fileset dir="${report}/xml">
<include name="TEST*.xml" />
</fileset>
<report format="frames" todir="${report}/html" />
</junitreport>
</target>
</project>

Run the following ant command

C:\WORKSPACE\JavaProject\ant