• About Selenium

    Selenium automates browsers. That's it! What you do with that power is entirely up to you. Primarily, it is for automating web applications for testing purposes, but is certainly not limited to just that. Boring web-based administration tasks can (and should!) also be automated as well.

    Read More
  • About TestNG

    TestNG is a testing framework inspired from JUnit and NUnit but introducing some new functionalities that make it more powerful and easier to use.TestNG is designed to cover all categories of tests: Unit, functional, end-to-end, integration, etc., and it requires JDK 5 or higher

    Read More

Monday, August 25, 2014

Selenium integration with maven

We use Maven on the vast majority of our projects and we often use Jetty as a web container in plain Java web projects (i.e. those that don’t require a full JEE container). Often the deployment environment is not Jetty (it might be Oracle AS or WebLogic for example) but Jetty is so well integrated with Maven that the costs of not developing on the deployment platform are outweighed by the ease-of-development benefits.
Selenium is a common choice for writing integration tests for web application – and one that we have used on various projects in the past. The idea is that you interact with your web application using Firefox and the Selenium IDE plugin records the test. You can then replay this test as part of the ‘integration-test’ Maven phase for your application, hence building up a suite of integration tests to run.
Putting all of this together, we’d like to share with you the Maven configurations and Java code that we use to accomplish automated one-step Selenium integration testing for a web application running in Jetty using Maven.
For the purposes of this post, we will refer to a Spring-MVC Java web application that keeps track of cars. It has the ability to add/delete/edit/list cars. To keep things simple, it does not use a database but keeps a list of cars in memory. The full code for the application can be downloaded from here.
Pre-requisites: Maven installed, some understanding of Selenium is helpful.

Run the web application

Download the source code (available here) and unzip it to a folder on your filesystem. Open a console and navigate to the folder with the code in it and execute the following:
mvn jetty:run
In your browser, go to the application homepage: http://localhost:9080/integration-testing-post and you should see the following:
Integration Testing Cars Application homepage
Integration Testing Cars Application homepage
Once you’ve navigated around the application, stop it by pressing ctrl-C in the console.

Open the application in Eclipse

Navigate to the directory to which you downloaded the source code in the console. Run the following to Generate the Eclipse project descriptors:
mvn eclipse:eclipse
Then, open Eclipse and run File > Import and choose Existing Projects Into Workspace. Hit ‘next’ and then browse for the directory into which you downloaded the code. Click ok and then Eclipse should find your new project. Double-click on it to import it. You may have to add the M2_REPO classpath variable to your workspace if you’ve not already done so. See here for more info.

Create the Selenium Integration Test

The integration tests are in the /src/test/java/com/tsl/example/cars/integration/ folder of the project. SeleniumIntegrationTest is the base class for all Selenium tests. It starts up a Selenium client in the setup() method and stops it in the tearDown() method.
package com.tsl.example.cars.integration;
 
import junit.framework.TestCase;
 
import org.openqa.selenium.server.SeleniumServer;
 
import com.thoughtworks.selenium.DefaultSelenium;
import com.thoughtworks.selenium.Selenium;
 
public abstract class SeleniumTestCase extends TestCase {
 
 protected Selenium selenium;
 
 @Override
 protected void setUp() throws Exception {
  super.setUp();
        selenium = new DefaultSelenium(
          "localhost", 
          SeleniumServer.getDefaultPort(), 
          "*iehta", 
          "http://localhost:9080");
        selenium.start();
 }
 
    @Override
    protected void tearDown() throws Exception {
     selenium.stop();
     super.tearDown();
    }
}
For more information on the parameters passed in the constructor of DefaultSelenium, see the Selenium client documentation. The most important is that which specifies the browser that Selenium should use to run the tests. In this case, it is set to "*iehta" which means Internet Explorer. To change to Firefox, use "*firefox".
CarIntegrationTest is a Selenium Integration Test. It extends SeleniumTestCase. The source code is below:
package com.tsl.example.cars.integration;
 
public class CarIntegrationTest extends SeleniumTestCase {
 
 public void testAddCar() throws Exception {
  selenium.open("/integration-testing-post/cars/list.html");
  selenium.click("link=Add Car");
  selenium.waitForPageToLoad("30000");
  selenium.type("make", "Mercedes");
  selenium.type("model", "SLK");
  selenium.click("btnSave");
  selenium.waitForPageToLoad("30000");
  assertTrue(selenium.isTextPresent("Mercedes"));
  assertTrue(selenium.isTextPresent("SLK"));
 } 
}
The testAddCar() method tests that we can add a car (a Mercedes SLK) using the web application. It assumes that you start at the start page of the application, click on the ‘add car’ link, enter the make and model and click save. It waits up to 30secs for the application to save the car and tests that on the resulting page (which is the list of cars), the words ‘Mercedes’ and ‘SLK’ appear. This allows us to assume that the car was correctly added.
The content of this test method was generated using the Selenium IDE plugin for Firefox:
Selenium IDE plugin in Firefox
Selenium IDE plugin in Firefox
I’m not going to go into detail here on how to use the Selenium IDE but basically it acts like a Macro recorder – recording your steps as you manually perform the integration test in your browser and then allowing you to play it back. I prefer standard Java syntax for the test instead of the ‘Selenese’ default. You can export Java code from a new test case by choosing File > Export Test Case As > Java – Selenium RC. I tend to create a new class manually in Eclipse for the test and then copy over just the testXXX methods from the Java source code that I exported from Selenium IDE.

Running the integration tests in Jetty using Maven

Once we have created an integration test we want to run it using Maven. There are a few things we want to happen before the integration test runs though:
  1. Start up the web application running in Jetty
  2. Start up the Selenium Server
We accomplish this using the following section in the Maven POM file (in the root folder of the downloaded code):
   <build>
      <plugins>
         <plugin>
            <groupId>org.mortbay.jetty</groupId>
            <artifactId>maven-jetty-plugin</artifactId>
            <configuration>
               <scanIntervalSeconds>5</scanIntervalSeconds>
               <stopPort>9966</stopPort>
               <stopKey>foo</stopKey>
               <connectors>
                  <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
                     <port>9080</port>
                     <maxIdleTime>60000</maxIdleTime>
                  </connector>
               </connectors>
            </configuration>
            <executions>
               <execution>
                  <id>start-jetty</id>
                  <phase>pre-integration-test</phase>
                  <goals>
                     <goal>run</goal>
                  </goals>
                  <configuration>
                     <daemon>true</daemon>
                  </configuration>
               </execution>
               <execution>
                  <id>stop-jetty</id>
                  <phase>post-integration-test</phase>
                  <goals>
                     <goal>stop</goal>
                  </goals>
               </execution>
            </executions>
         </plugin>
         <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
               <source>1.5</source>
               <target>1.5</target>
               <encoding>UTF-8</encoding>
            </configuration>
         </plugin>
         <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>selenium-maven-plugin</artifactId>
            <version>1.0-beta-3</version>
            <executions>
               <execution>
                  <id>start</id>
                  <phase>pre-integration-test</phase>
                  <goals>
                     <goal>start-server</goal>
                  </goals>
                  <configuration>
                     <background>true</background>
                     <logOutput>true</logOutput>
                     <multiWindow>true</multiWindow>
                  </configuration>
               </execution>
               <execution>
                  <id>stop</id>
                  <phase>post-integration-test</phase>
                  <goals>
                     <goal>stop-server</goal>
                  </goals>
               </execution>
            </executions>
         </plugin>
         <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <configuration>
               <excludes>
                  <exclude>**/integration/*Test.java
                  </exclude>
               </excludes>
            </configuration>
            <executions>
               <execution>
                  <id>integration-tests</id>
                  <phase>integration-test</phase>
                  <goals>
                     <goal>test</goal>
                  </goals>
                  <configuration>
                     <skip>false</skip>
                     <excludes>
                        <exclude>none</exclude>
                     </excludes>
                     <includes>
                        <include>**/integration/*Test.java
                        </include>
                     </includes>
                  </configuration>
               </execution>
            </executions>
         </plugin>
      </plugins>
   </build>
I’m among the first to acknowledge the benefits of Maven, but at times the XML syntax required to configure it can be a bit scary! Here’s the basic explanation of all this:
  • The Jetty plugin is configured to run Jetty on port 9080 – I prefer to avoid potential conflicts with other applications running on 8080 which is quite commonly used.
  • In the pre-integration-test Maven phase (executed before the integration tests are run), the run goal of the Maven Jetty plugin is executed. The configuration element allows us to specify that that this is a daemon process
  • In the post-integration-test phase, we run the stop goal of the Maven Jetty plugin to shut down Jetty.
  • In the pre-integration-test phase we run the start-server goal of the Maven Selenium Plugin
  • In the post-integration-test phase, we run the stop-server goal of the Maven Selenium plugin to shut down the Selenium server
  • The Maven Surefire plugin is configured to not execute the integration tests as part of the normal test phase but instead in the integration-test phase.

Executing the Integration tests

Although the Maven configuration looks verbose and complicated, it gives great results. Just executing the single command below in the console causes the integration tests to run without interference:
mvn integration-test

What about Cargo?

When I was developing this code, I noticed that many people seemed to use the Maven Cargo plugin to start up the relevant application server. I had very mixed results using this with different application servers and it didn’t seem to work at all with Jetty – lots of Classpath problems if I remember rightly. In the end, the plain old Maven Jetty plugin did the job just fine.

Thursday, August 21, 2014

Integrating Selenium Tests into HP Quality Center/ALM as TestCases

Integrating Selenium Tests into HP Quality Center/ALM as TestCases

By embedding the Selenium Test Suite directly in HP Quality Center as a TestCase you get:
  • A repository for your testing asset
  • Traceability from TestCases 
  • Full control of testdata
  • Execution history
  • Version control for your Selenium TestSuites and TestCases
  • Accellerated defect creation
  • Full use of the Selenium featureset
This release of the SELENIUM_TEST only supports JAVA based TestSuites and TestCases.

HP Quality Center/ALM as Repository for Selenium TestSuites

 

The test is created as any other test in TestPlan. The test type is SELENIUM_TEST and the test has fields and links just like any other test.
After creating the testcase the Selenium TestSuite is uploaded and it displays in the Test Script tab:


The different browsers for the test is defined on the Test Configurations tab. Other data for a datadriven test can also be defined here-


Keeping track of Executions with TestLab

In Test Lab the SELENIUM_TEST is added to a Test Set. When executing the test it launches with ANT and the results are saved back into Quality Center. In this way each Test in TestSet has a run history that contains repoports from both passed and failed runs:



Traceability

With HP Quality Centers build-in traceability:
  • Selenium TestCases can be linked to Requirements
  • Using testconfigurations different browsers can be tested using the same test, and tracking the results for each browser
  • Defects can be created with autogenereated run results, and linked to the test run

Version control

With HP Quality Centers build-in version control:
  • The Selenium TestSuite and TestCases can be versioncontrolled
  • The parametervalues entered in the testconfigurations can be versioncontrolled

Accellerated defect creation

 When creating a defect directly from the Run report, the defect gets:
  • The errorlog as Description
  • All log files as attachments
  • The JAVA source files and an ANT buildscript as attachments
It is automatically linked to the testinstance in the testset and to the run. All required fields are displayd in order to make sure a valid defect is created.




Source : http://toolintegrator.com/index.php/selenium-integration

Selenium Integration with Jenkins

Operate PushToTest TestMaker tests from Continuous Integration environments. PushToTest checks TestMaker compatibility with Hudson and Bamboo. 
1. Product Version Details
TestMaker Version : 5.5 RC3
Bamboo Version : 
2.6.2 (Standalone)
Hudson Version : 
1.374
Java Verison : 
1.6 (1.6.18 or later)
Tomcat Verison : 
6.0.26 (To run Hudson)
2. Setup Build to run tests in Hudson (Windows - localhost)
  • Setup a build in Hudson
  • Pre-requisite to execute the build
  • Execute the build in Hudson
  • Configure the build/test output to detect failures in Junit output
Setup a build in Hudson:
Hudson comes with a web archive file (hudson.war). You need a web server (tomcat/jboss/jetty) to run Hudson.
Tomcat Console (runs in 8090 http port)
Tomcat Console

Hudson Home

Create New Job link to create a new Job

Create New Job link

Click OK to proceed

OK to proceed

You can select Source Code Management option to checkout the code from (CVS/Subversion). All the source/tests will checkout in the build workspace directory.

Select Execute Windows build Command from the Build

Execute

Type the following command

%TESTMAKER_HOME%\TestMaker.cmd -t example_agents\AjaxRIASeleniumTest_Tutorial\Calendar_Functional_Test.scenario -log-junit testreport\junitreport.xml

Note: The scenario file path (example_agents\AjaxRIASeleniumTest_Tutorial\Calendar_Functional_Test.scenario) and reports path (testreport\junitreport.xml
) is relative to your build workspace.

Calendar function


Click Save.

Pre-requisite to execute the build:

Create Environment variables:

Create the below two environment variables in Hudson Console (Hudson -> Manage Hudson -> Configure Your System -> Global Properties) as shown below:

JAVA_HOME
TESTMAKER_HOME
TestMaker Home

TestMaker

TestMaker

Or you can create these two system environment variables (My computer -> Advanced -> Environment Variables)
Environment Variables
Environment Variable

Start TestNode:

If required, start the Testmaker testnode. The current example is using the local testnode which runs in 8080 http port.

Testnode console
Testnode console


Execute the build in Hudson:

Hudson

Click on Build Now link available in the left side to start the build
Build Now

Due to some reason, the first build failed, so I ran the build for the second time.

You can watch the logs by clicking the build link build link

logs

Click on the Console output


Console Output

In the meantime, you can watch the testnode logs:

testnode logs



Configure the build/test output to detect failures in Junit output:

Check the Publish JUnit test result report option from the Post-build Actions

Post-build actions

Note: You may not have the report file for the first time build. So, do not select this option until unless you have the report file (junitreport.xml) available in the specified directory.

Click on the Test Result
Test Results

Test Results

3. Setup Build to run tests in Hudson (Linux - localhost)
  • Setup a build in Hudson
  • Pre-requisite to execute the build
  • Execute the build in Hudson
  • Configure the build/test output to detect failures in Junit output
Setup a build in Hudson:

Same as windows - Please refer windows section

build

You can select Source Code Management option to checkout the code from (CVS/Subversion). All the source/tests will checkout in the build workspace directory.

Select Execute Shell from the Build

Execute Shell

Type the following command

$TESTMAKER_HOME/TestMaker.sh -t example_agents/AjaxRIASeleniumTest_Tutorial/Calendar_Functional_Test.scenario -log-junit testreport/junitreport.xml

Note: The scenario file path (example_agents/AjaxRIASeleniumTest_Tutorial/Calendar_Functional_Test.scenario) and reports path (testreport/junitreport.xml
) is relative to your build workspace.

Make sure the / , $, TestMaker.sh

TestMaker


Click Save.

Pre-requisite to execute the build:

Create Environment variables:

--Same as Windows

But only the Path is going to change. It has to be valid unix path.


unix path

Start the TestNode:

--Same as Windows


Execute the build in Hudson:

--Same as Windows

Configure the build/test output to detect failures in Junit output:

--Same as Windows