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

Friday, 28 December 2012

"Failed to start: SocketListener0@0.0.0.0:4444" while Selenium RC Test Execution

Many of us face this common error while trying to execute tests after a successful test run. This is because of the Selenium server that starts on port 4444 and fail to shutdown, throwing an error message on forthcoming tests.

WARN - Failed to start: SocketListener0@0.0.0.0:4444


There are couple of alternate ways to overcome this

#1
1| Open a new tab from your web browser.
2| Copy and paste the below URL.
http://localhost:4444/selenium-server/driver/?cmd=shutDownSeleniumServer
3| Soon-after hitting Enter button, a get response 'okok' will be obtained; it make sure that the Selenium server is shutdown on port 4444.








4| Now, its time to re-run your test on port 4444.

#2
1| Open cmd
2| Force Selenium server to listen port other other than 4444. i.e., 5555 or other
java -jar selenium-server-standalone-x.xx.x.jar -p 5555

Handling browser-level authentication | Selenium


Whenever a site prompts for an username and password, make use of the following script to override such authentication,

driver.get("http://username:password@site.com/page");

e.g., driver.get("http://admin:root@site.com/page");

Thursday, 27 December 2012

Maven | Selenium Test Execution

Text in ORANGE has to be edited by users or mentioned important through-out this BLOG

Maven is the Central Repository [like a server], where it can store the jar files. Here, we use Maven as a test execution framework.

Set Maven Environment

1| Download Maven apache-maven-x.x.x-bin.zip
2| Unzip the folder under C:\Program Files\
3| Create a new System Variable under 'Environment Variables'.
Variable: M2_HOME
Value: C:\Program Files\apache-maven-3.0.4


4| Add Maven path under the variable name, 'Path'
Variable value: %M2_HOME%\bin


5| Make sure that maven is configured properly.
6| Open cmd prompt.
7|Type 'mvn -version'


  
Configure Maven on Eclipse

1| Install Maven plugin in Eclipse IDE using "Eclipse Marketplace.."
2| Create a new 'Maven project' in Eclipse IDE.
Right click on Package Explorer > New > Other
3| Type 'maven' and Click Next.



4| Select the Project location and Click Next.
5| Select an Archetype as shown below and Click Next.


6| Enter the 'Group Id' and 'Artifact Id' and Click Finish.



7| Now, you will see a POM file created below target folder.



Modify POM.xml

1| Create a new class file under src/test/java; Here it is 'AppTest.java'
2| Open the POM xml file.
3| Add the following dependencies for a simple test execution.
JUnit, TestNG, selenium-server, selenium-java

This is how the POM looks like,

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>mvngrp</groupId>
  <artifactId>mvnart</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>mvnart</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>


    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.testng</groupId>
      <artifactId>testng</artifactId>
      <version>6.8</version>
    </dependency>   

    <dependency>
      <groupId>org.seleniumhq.selenium</groupId>
      <artifactId>selenium-server</artifactId>
      <version>2.35.0</version>
    </dependency>
    <dependency>
      <groupId>org.seleniumhq.selenium</groupId>
      <artifactId>selenium-java</artifactId>
      <version>2.35.0</version>
    </dependency>

 
  </dependencies>
</project>


4| The build libraries mentioned under dependencies will automatically added into the project soon-after saving the POM.xml


Maven Test Execution

There are couple of ways to execute Maven Test.

#1
1| In eclipse, right click on the POM.xml > Run As > Maven install


2| In-order to clean existing test results, it is important to 'Maven clean' before executing a new test.
right click on the POM.xml > Run As > Maven clean

#2
1| Open cmd prompt.
2| Move into the project folder.
3| Type 'mvn clean'
4| Type 'mvn install' for test execution



Note| If you've trouble on creating Maven projects using maven-archetype-quickstart [Eclipse],
1| Open cmd prompt
2| Locate the workspace
3| Enter the below to create a maven project
mvn archetype:generate -DgroupId=yourgroupid -DartifactId=yourartifactid -DarchetypeArtifactId=maven-archetype-quickstart