Friday, May 7, 2010

Using TestNG for parallel execution on Selenium Grid

Following I will mention how to integrate TestNG with Selenium-Grid code and use it for parallel execution of test cases.
For this you create a Base class where you define the following two functions.


protected
void startSession(String seleniumHost, int seleniumPort, String browser, String webSite)
throws Exception {


startSeleniumSession(seleniumHost, seleniumPort, browser, webSite);

session().setTimeout(TIMEOUT);

}

protected void closeSession() throws Exception {

closeSeleniumSession();

}

The above two functions are for the starting and closing the session in Selenium Grid. The references of it can be found in my earlier posts.

Now import the testng annotation class “org.testng.annotations.*” onto the Base Class.

Add @BeforeClass before the “startSession” method and @AfterClass before the “closeSession” method.

Now write your test cases in a way that all dependent test cases are in one class.


So whenever you execute the testNG it will call the “startSession” and “closeSession” before and after each test class execution. The “startSession” will create a Selenium session for test execution and return it to the test class. Where as the “closeSession” will close the session.

For parallel execution define inside the testng.xml file the attributes “suite” tag as “parallel="classes" thread-count="2" ”.
This will tell TestNG that parallel execution needs to be done for classes and max. Thread count for it is “2”.

Define 2 different test classes both extending the Base Class which defines the “startSession” and “closeSession” methods. Start a Selenium Grid Hub and register two Selenium remote control to the Hub. Now try running the package containing these classes using the TestNG.

You will see 2 different tests running in parallel in Selenium Grid each for Selenium Remote Control registered to the Hub.
The “startSeleniumSession” inside the “startSession” method create a unique selenium session for each of the test class and use that session for test class execution. Creating a session,registering the session with a Remote control and maintaining the session is done by Selenium Grid where as using TestNG framework we define how many sessions we need to create and how the test execution should be. So using the features of both TestNG and Selenium Grid we achieve Parallel execution of our automation testcases.

Currently here I had suggested to use @Before/AfterClass annotations in Base Class. You can use any of the other available @Before/After annotations available in TestNG depending upon your tests.

11 comments :

Jailtonjr said...

hey Varun, I can't run my testes... I follow all steps and it can't working correctly.. Could you help me?

Look my code:

package br.com.politec.testng;

import com.thoughtworks.selenium.*;

import org.testng.annotations.*;

import static com.thoughtworks.selenium.grid.tools.ThreadSafeSeleniumSessionStorage.closeSeleniumSession;
import static com.thoughtworks.selenium.grid.tools.ThreadSafeSeleniumSessionStorage.session;
import static com.thoughtworks.selenium.grid.tools.ThreadSafeSeleniumSessionStorage.startSeleniumSession;
import static org.testng.Assert.*;
import java.util.regex.Pattern;


public class GoogleTestNG {

private static final String TIMEOUT = null;
static Selenium selenium = session();

public static void main(String[] args) throws InterruptedException {
GoogleTestNG test1= new GoogleTestNG();
try {

test1.startSession("http://localhost", 6666, "*firefox", "http://10.62.1.37:7080/");
// test1.startSession("localhost", 5555, "*firefox", "http://10.62.1.37:7080/");

} catch (Exception e) {
e.printStackTrace();
}



test1.testGoogleTestNG();
}


@BeforeClass
protected void startSession(String seleniumHost, int seleniumPort, String browser, String webSite) throws Exception {

startSeleniumSession(seleniumHost, seleniumPort, browser, webSite);

selenium.setTimeout(TIMEOUT);

}

@AfterClass
protected void closeSession() throws Exception {

closeSeleniumSession();

}


@Test
public void testGoogleTestNG() {

for (int i = 0; i < 10; i++) {

selenium.open("/anp-cas/login?service=http%3A%2F%2F10.62.1.37%3A7080%2Fanp-sigef-intranet-web%2Fj_spring_cas_security_check");
selenium.type("username", "ADMIN"+i);
selenium.type("password", "ADMIN"+i);
selenium.type("captcha", "ADMIN");
selenium.click("//input[@value='Login']");


}
}
}

Tarun K said...

U missed to mention error u encounter!
did u try providing full app url in here -

selenium.open("/anp-cas/login?service=http%3A%2F%2F10.62.1.37%3A7080%2Fanp-sigef-intranet-web%2Fj_spring_cas_security_check")

Varun Menon said...

Tarun I suppose his issue was that TestNG was not working. The Main class he had written may not be required. As TestNG itself identify the test class from the testng xml and execute it accordingly.

Tarun K said...

okie

amol said...

Hi I have used this but I am facing two errors Could you please help out for resolving those since I am new to Selenium Grid

1- Unable to use parallel with suite. Its giving error
Code - " "

Error - "[Parser] [WARN] Unknown value of
attribute 'parallel' at suite level: 'classes'."


2 - Unable to pass parameters to startSession method.

Code - " package script.login;

import com.thoughtworks.selenium.*;

import org.junit.AfterClass;
import org.testng.annotations.*;

import static com.thoughtworks.selenium.grid.tools.ThreadSafeSeleniumSessionStorage.startSeleniumSession;
import static com.thoughtworks.selenium.grid.tools.ThreadSafeSeleniumSessionStorage.closeSeleniumSession;
import static com.thoughtworks.selenium.grid.tools.ThreadSafeSeleniumSessionStorage.session;

public class login01 extends SeleneseTestCase{

public static String TIMEOUT="30000";




@BeforeClass
protected void startSession(String seleniumHost, int seleniumPort, String browser, String webSite)
throws Exception {

startSeleniumSession(seleniumHost, seleniumPort, browser, webSite);
session().setTimeout(TIMEOUT);

}

@Test
public void login_amol(){
session().type("loginId", "amol");
session().type("password", "Amol0987");
session().click("Submit");
session().waitForPageToLoad(TIMEOUT);
}

@Test(dependsOnMethods="login_amol", alwaysRun=true)
public void logout_amol() throws Exception{
session().click("link=Logout");
assertTrue(session().isTextPresent("User amol logged out successfully!"));
}

@AfterClass
protected void closeSession() throws Exception {
closeSeleniumSession();
}

}
"

Error - " FAILED CONFIGURATION: @BeforeClass startSession
org.testng.TestNGException:
Method startSession requires 4 parameters but 0 were supplied in the @Configuration annotation.
... Removed 20 stack frames "

amol said...

I am facing two errors. please help out for resolving those since I am new to Selenium Grid

1- Unable to use parallel with suite. Its giving error
XML Code - " "

Error - "[Parser] [WARN] Unknown value of attribute 'parallel' at suite level: 'classes'."


2 - Unable to pass parameters to startSession method.

Code -
package script.login;

import com.thoughtworks.selenium.*;

import org.junit.AfterClass;
import org.testng.annotations.*;

import static com.thoughtworks.selenium.grid.tools.ThreadSafeSeleniumSessionStorage.startSeleniumSession;
import static com.thoughtworks.selenium.grid.tools.ThreadSafeSeleniumSessionStorage.closeSeleniumSession;
import static com.thoughtworks.selenium.grid.tools.ThreadSafeSeleniumSessionStorage.session;

public class login01 extends SeleneseTestCase{

public static String TIMEOUT="30000";




@BeforeClass
protected void startSession(String seleniumHost, int seleniumPort, String browser, String webSite)
throws Exception {

startSeleniumSession(seleniumHost, seleniumPort, browser, webSite);
session().setTimeout(TIMEOUT);

}

@Test
public void login_amol(){
session().type("loginId", "amol");
session().type("password", "Amol0987");
session().click("Submit");
session().waitForPageToLoad(TIMEOUT);
}

@Test(dependsOnMethods="login_amol", alwaysRun=true)
public void logout_amol() throws Exception{
session().click("link=Logout");
assertTrue(session().isTextPresent("User amol logged out successfully!"));
}

@AfterClass
protected void closeSession() throws Exception {
closeSeleniumSession();
}

}


Error -
FAILED CONFIGURATION: @BeforeClass startSession
org.testng.TestNGException:
Method startSession requires 4 parameters but 0 were supplied in the @Configuration annotation.
... Removed 20 stack frames

Praveen Kittali said...

Hi Varun,

Is there any way of running tests parallel without using TestNG?

Regards,
Praveen

Praveen Kittali said...

To add more details, I want to run a series of methods thats within one Java program and have them run in parallel. I do not want to use testng.xml. As in testng.xml each test is a single Java program.

Varun Menon said...

Couldnt get you.. In case you want to do it by urself you have to do multi-threading.

Bhaskar Boss said...

Can anybody Please provide me code to generate custom reports using TestNG framework, Condition is to use TestNg Listeners.

Varun Menon said...

Look at the following url:

http://testng.org/doc/documentation-main.html#logging

Post a Comment