Parallel execution of tests in testNG Selenium - java

I am not able to invoke the browsers in parallel, which are currently invoking one after another. Need a way to invoke the browsers in parallel tests.
NOTE: In my configuration xml file I have kept the thread count as 2.
Below is my configuration file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "testng.org/testng-1.0.dtd"; >
<suite name="Parallel" parallel="tests" thread-count="4" >
<test verbose="3" name="<name>">
<parameter name="platform" value ="win8"/>
<parameter name="browsername" value ="internet explorer"/>
<classes>
<class name="com.parallel.execution.ParallelExecution">
<methods>
<include name="testmethod1"/>
</methods>
</class>
</classes>
</test>
</suite>

We have to define two attributes 'parallel' and 'thread-count' in simple testng.xml file. See below:
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Parallel Execution suite" parallel="methods" thread-count="2">
<test name="Regression 2">
<classes>
<class name="com.parallel.TestParallelExecution"/>
</classes>
</test>
</suite>
In above, as we want the test methods to be executed parallel, we have set the parallel attribute as 'methods' and thread-count attribute will control the max number of threads to be created.
Re-installing TestNG solved the above problem.

You have to explicitly write code to invoke the browser as part of a #Before configuration to invoke the browser every time a #Test is run . I will specify one of the many approaches so that you get an idea.
<suite name="Parallel" parallel="tests" thread-count="4" >
<test verbose="3" name="test1">
<classes>
<class name="com.parallel.execution.ParallelExecution1"/>
</classes>
</test>
<test verbose="3" name="test2">
<classes>
<class name="com.parallel.execution.ParallelExecution2"/>
</classes>
</test>
</suite>
Consider a suite file with 2 tests set to run in parallel. What we expect is #Test methods in ParallelExecution1 runs in first browser and #Test methods in ParallelExecution2 runs in second browser. So you need a mechanism by which you can invoke browser sessions and run your test methods. Enter BaseTest class.
public abstract class BaseTest {
protected WebDriver driver;
#BeforeTest
#Parameters({"browser"})
public void init(String browser) {
// Initialize your browser here. Code below is dummy
driver = new FF();
}
#AfterTest
public void end() {
driver.close();
driver.quit();
}
}
Now inherit this 'BaseTest' in both your test classes.
public class ParallelExecution1 extends BaseTest {
#Test
public void test1() {
}
}
public class ParallelExecution2 extends BaseTest {
#Test
public void test2() {
}
}
Now both the tests have #BeforeTest and #AfterTest methods which will invoke the browsers.

Related

Selenium: TestNG: Tests are not running in parallel

I have a simple maven project with three class files.
When I run my testng.xml file, tests are running in series.
I tried keeping parallel="classes", parallel="methods", parallel="tests" but no luck.
Also tried by changing testng version from 6.9.0 to 7.0.0 but it didn't work.
Expectation:
Tests should run in parallel
What is happening:
Tests run in sequence
Below is my project and all files:
Test Class: 1
public class TestOne {
private static WebDriver driver;
private static String baseURL;
#Test
public void launch() throws IOException {
baseURL = "http://www.gmail.com";
System.setProperty("webdriver.chrome.driver", "path");
WebDriver driver = new ChromeDriver();
driver.get(baseURL);
driver.quit();
}
}
Test Class: 2
public class TestTwo {
private static WebDriver driver;
private static String baseURL;
#Test
public void launch() throws IOException {
baseURL = "http://www.gmail.com";
System.setProperty("webdriver.chrome.driver", "path");
WebDriver driver = new ChromeDriver();
driver.get(baseURL);
driver.quit();
}
}
Test Class: 3
public class TestThree {
private static WebDriver driver;
private static String baseURL;
#Test
public void launch() throws IOException {
baseURL = "http://www.gmail.com";
System.setProperty("webdriver.chrome.driver", "path");
WebDriver driver = new ChromeDriver();
driver.get(baseURL);
driver.quit();
}
}
TestNG xml:
!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"
suite name="Test" parallel="tests" thread-count="3" data-provider-thread-count="5"
<test name="Launch">
<classes>
<class name="test.demo.grid.TestOne" />
<class name="test.demo.grid.TestTwo" />
<class name="test.demo.grid.TestThree" />
</classes>
</test>
Version:
selenium-java = 3.4.0
testng = 6.14.3
=================================
Please let me know how I can fix it.
Thank you!
Try first a simple example logging the thread id on each test method, without calling ChromeDriver yet
long id = Thread.currentThread().getId();
System.out.println("Sample test-method " + testName
+ ". Thread id is: " + id);
https://howtodoinjava.com/testng/testng-executing-parallel-tests/
If it logged the ids in parallel maybe is something related to ChromeDriver
<test> tag is only one in your testng.xml and that is the reason, parallel execution is not working.
In your case, you need to use parallel="classes" and all the classes would execute parallely.
Edit:
You can use the testng.xml as:
<test name="Launch">
<classes>
<class name="test.demo.grid.TestOne" />
</classes>
</test>
<test name="Second test">
<classes>
<class name="test.demo.grid.TestTwo" />
</classes>
</test>
<test name="Third test">
<classes>
<class name="test.demo.grid.TestThree" />
</classes>
</test>
And now use parallel="tests" in the testng.xml
Try with parallel="classes" and without the data-provider-thread-count="5" because you are not using data provider here.
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Test" parallel="classes" thread-count="3">
<test name="Launch">
<classes>
<class name="test.demo.grid.TestOne" />
<class name="test.demo.grid.TestTwo" />
<class name="test.demo.grid.TestThree" />
</classes>
</test>
</suite>
You can try:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite" configfailurepolicy="continue">
<parameter name="parallelSetup" value="tests" />
<parameter name="threadsNumber" value="3" />
<test name="Launch">
<classes>
<class name="test.demo.grid.TestOne" />
<class name="test.demo.grid.TestTwo" />
<class name="test.demo.grid.TestThree" />
</classes>
</test>
</suite>
add #BeforeClass annotation in every class and initialize WebDriver in that annotaion
and close driver in #AfterClass annotion for every class

Test suites in Junit 5

I have several test classes sharing extending the BaseTest.class as following
class BaseTest{
#BeforeAll
static setup(){
// code to setup some configs for tests
}
}
AND
class TestClass1 extends BaseTest{
#Test
void test1(){
// test code
}
}
class TestClass2 extends BaseTest{
#Test
void test2(){
// test code
}
}
My need is to run these two tests in Parallel, but on different parameters passed to setup() method in BaseTest class, I found it easy in TestNg using testng.xml, but i need to use Junit5 to achieve this, Example from testng is
<suite name="Test-class Suite" parallel="classes" thread-count="2">
<test name="Test-class test 1">
<parameter name="paramName" value="paramValue1" />
<classes>
<class name="TestClass1" />
<class name="TestClass2" />
</classes>
</test>
<test name="Test-class test 2">
<parameter name="paramName" value="paramValue2" />
<classes>
<class name="TestClass1" />
<class name="TestClass2" />
</classes>
</test>
</suite>
I want your help to hear some suggestions/ideas how can i achieve this goal using Junit5, I appreciate all you inputs !
Thanks in advance

TestNG - Order of Tests execution in selenium script

I'm using selenium 3.8.1 and TestNG 6.9.2 version,while test execution before completing the #Test method another #Test method is starts,because of this i'm getting error in selenium script After completion of Test Cases execution.
One Class
public class LoginPage{
#Test(priority=0)
public void test1(){
System.out.println(first test);
}
#Test(priority=1)
public void test2(){
System.out.println(Second test);
}
}
Second Class
public class HomePage{
#Test(priority=0)
public void test3(){
System.out.println(first test);
}
#Test(priority=1)
public void test4(){
System.out.println(Second test);
}
}
testng.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
<test name="Test" preserve-order="true">
<classes>
<class name="com.tests.day.modules.LoginPage"/>
<class name="com.tests.day.modules.HomePage"/>
</classes>
</test>
</suite>
After Executing the above using testng.xml file before completing the test2 of login page class,test3 is starting of HomePage,because of this i'm getting exception,Unable to Find the Elements.
The Annotations mentions about the preserve-order attribute of TestNG as follows:
By default, TestNG will run your tests in the order they are found in
the XML file. If you want the classes and methods listed in this file
to be run in an unpredictable order, set the preserve-order attribute
to false
I executed the same test similar to your code block and testng.xml as follows :
LoginPage
package testng_order_of_tests_execution;
import org.testng.annotations.Test;
public class LoginPage
{
#Test(priority=0)
public void test1(){
System.out.println("First Test");
}
#Test(priority=1)
public void test2(){
System.out.println("Second Test");
}
}
HomePage
package testng_order_of_tests_execution;
import org.testng.annotations.Test;
public class HomePage
{
#Test(priority=0)
public void test3(){
System.out.println("first test");
}
#Test(priority=1)
public void test4(){
System.out.println("second test");
}
}
testng.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
<test name="Test" preserve-order="true">
<classes>
<class name="testng_order_of_tests_execution.LoginPage"/>
<class name="testng_order_of_tests_execution.HomePage"/>
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
What I found as an output on my console was similar to yours as follows :
First Test
first test
Second Test
second test
This Console Output apparently gives us an impression that the sequence of execution was :
test1() -> test3() -> test2() -> test4()
But actually No
Looking at the Result of running suite you will get the actual sequence of execution as per the figure below :
So it's pretty clear that the actual sequence was :
test1() -> test2() -> test3() -> test4()
Trivia
You can be more granular in your observation with the testng-results.xml which is as follows :
<?xml version="1.0" encoding="UTF-8"?>
<testng-results skipped="0" failed="0" ignored="0" total="4" passed="4">
<reporter-output>
</reporter-output>
<suite name="Suite" duration-ms="61" started-at="2017-12-25T12:57:12Z" finished-at="2017-12-25T12:57:12Z">
<groups>
</groups>
<test name="Test" duration-ms="61" started-at="2017-12-25T12:57:12Z" finished-at="2017-12-25T12:57:12Z">
<class name="testng_order_of_tests_execution.HomePage">
<test-method status="PASS" signature="test3()[pri:0, instance:testng_order_of_tests_execution.HomePage#5419f379]" name="test3" duration-ms="4" started-at="2017-12-25T18:27:12Z" finished-at="2017-12-25T18:27:12Z">
<reporter-output>
</reporter-output>
</test-method> <!-- test3 -->
<test-method status="PASS" signature="test4()[pri:1, instance:testng_order_of_tests_execution.HomePage#5419f379]" name="test4" duration-ms="1" started-at="2017-12-25T18:27:12Z" finished-at="2017-12-25T18:27:12Z">
<reporter-output>
</reporter-output>
</test-method> <!-- test4 -->
</class> <!-- testng_order_of_tests_execution.HomePage -->
<class name="testng_order_of_tests_execution.LoginPage">
<test-method status="PASS" signature="test1()[pri:0, instance:testng_order_of_tests_execution.LoginPage#735b5592]" name="test1" duration-ms="14" started-at="2017-12-25T18:27:12Z" finished-at="2017-12-25T18:27:12Z">
<reporter-output>
</reporter-output>
</test-method> <!-- test1 -->
<test-method status="PASS" signature="test2()[pri:1, instance:testng_order_of_tests_execution.LoginPage#735b5592]" name="test2" duration-ms="2" started-at="2017-12-25T18:27:12Z" finished-at="2017-12-25T18:27:12Z">
<reporter-output>
</reporter-output>
</test-method> <!-- test2 -->
</class> <!-- testng_order_of_tests_execution.LoginPage -->
</test> <!-- Test -->
</suite> <!-- Suite -->
</testng-results>
In testng-results.xml you will observe that all the tests starts at 2017-12-25T12:57:12Z and ends at 2017-12-25T12:57:12Z. Though the time taken for Test Execution is even less then 1 second still you may observe the difference in the instancename as instance:testng_order_of_tests_execution.HomePage#5419f379 and instance:testng_order_of_tests_execution.LoginPage#735b5592. As our test was a single threaded test, hence we can conclude that the sequence of execution was proper and as per expectation. But the Console Output got mixed up.
Use group-by-instances="true" inside test tag of the testng.xml
Define your xml test tag like below:
<test name="Test" group-by-instances="true">
Or, you can also check below line of code:
<test name="Test" preserve-order="true" group-by-instances="true">

Selenium: Run same test on different browsers

I want to run same test on different browsers (Firefox, Chrome and Safari). To do this I am using parametrization in tests. Where in if browser is chrome run chrome and so on.
And in testng.xml I have specified to run tests in parallel and repeated same test in under several <test> tags.
What if I have so many tests to run. I will be copy pasting same test in <test> tags. Which doesn't see optimal solution.
How can I fix this?
Here is what I tried:
public class SameTestDifferentBrowsers {
WebDriver driver;
#BeforeMethod
#Parameters("browser")
public void openBroswer(String browser) {
if (browser.equalsIgnoreCase("Chrome")) {
System.out.println(System.getProperty("user.dir"));
System.setProperty("webdriver.chrome.driver", System.getProperty("user.dir")+"//lib//browsers//chromedriverMac");
driver = new ChromeDriver();
} else if (browser.equalsIgnoreCase("Firefox")) {
driver = new FirefoxDriver();
} else if (browser.equalsIgnoreCase("safari")) {
System.setProperty("webdriver.safari.driver", System.getProperty("user.dir")+"//lib//browsers//SafariDriver.safariextz");
driver = new SafariDriver();
}
}
#AfterMethod
public void closeBrowser() {
driver.quit();
}
#Test
public void login_TestCase() {
driver.get("https://www.google.com");
}
}
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Parallel test suite" parallel="tests">
<test name="Firefox Test">
<parameter name="browser" value="browser"/>
<classes>
<class name="ParallelBrowser.SameTestDifferentBrowsers"/>
</classes>
</test>
<test name="Chrome Test">
<parameter name="browser" value="browser"/>
<classes>
<class name="ParallelBrowser.SameTestDifferentBrowsers"/>
</classes>
</test>
<test name="Safari Test">
<parameter name="browser" value="browser"/>
<classes>
<class name="ParallelBrowser.SameTestDifferentBrowsers"/>
</classes>
</test>
</suite>
If you are sure that you would want to run all the tests for all the three browsers then you may change your design a little.
Create multiple test classes for different test cases. In your xml test tags pass different test class names as parameters.
Write three #test methods in your parametrized test class each for each browser that accepts the class name as a parameter. Now using Reflections you can invoke the right test method in every #test method.
Two things require fixing here and the problem sill be solved.
First: Update the TestNG.xml file to include the browser names
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Parallel test suite" parallel="tests">
<test name="Firefox Test">
<parameter name="browser" value="Firefox" />
<classes>
<class name="ParallelBrowser.SameTestDifferentBrowsers" />
</classes>
</test>
<test name="Chrome Test">
<parameter name="browser" value="Chrome" />
<classes>
<class name="ParallelBrowser.SameTestDifferentBrowsers" />
</classes>
</test>
<test name="Safari Test">
<parameter name="browser" value="safari" />
<classes>
<class name="ParallelBrowser.SameTestDifferentBrowsers" />
</classes>
</test>
Second: Safari browser extension should be installed and enabled in the browser and shouldn't be kept in the path.
So just comment following line from Java Code File
//System.setProperty("webdriver.safari.driver",
//System.getProperty("user.dir") + "/lib/browsers/SafariDriver.safariextz");

how to run more then one selenium testing suite on the same machine

I am using Java/Selenium webdriver with testng to run my test automation, i have many automated project, each project is using a testing suite.xml, how can i run two suites or more at the same time on the same machine,
here is my code for the creation of the driverInstance object:
public WebDriver getDriverInstance(
String Url,
String browser ) throws MalformedURLException {
WebDriver driver = null;
URL url = new URL( Url );
if( browser.equals( "firefox" ) ) {
DesiredCapabilities capability = DesiredCapabilities.firefox();
driver = new RemoteWebDriver( url, capability );
} else if( browser.equals( "chrome" ) ) {
DesiredCapabilities capability = DesiredCapabilities.chrome();
driver = new RemoteWebDriver( url, capability );
} else if( browser.equals( "IE" ) ) {
DesiredCapabilities capability = DesiredCapabilities.internetExplorer();
driver = new RemoteWebDriver( url, capability );
}
return driver;
}
You need set attribute as parallel="tests" in your testng xml
<suite name="Parallel test runs" parallel="tests" thread-count="2">
There is the “parallel” parameter. Set to “tests” because we want to run tests parallel. The other parameter is the “thread-count”. If it is set to 2, than two browsers will be opened and the first two tests will run from the list. If the thread-count is 5 than five browsers will be opened and all the five tests will executed parallel!
For tests your testng.xml structure should be like below:-
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Parallel test runs" parallel="tests" thread-count="2">
<test name="T_01">
<classes>
<class name="testNG.Parallel.Test01" ></class>
</classes>
</test>
<test name="T_02">
<classes>
<class name="testNG.Parallel.Test02" ></class>
</classes>
</test>
<test name="T_03">
<classes>
<class name="testNG.Parallel.Test03" ></class>
</classes>
</test>
<test name="T_04">
<classes>
<class name="testNG.Parallel.Test04" ></class>
</classes>
</test>
<test name="T_05">
<classes>
<class name="testNG.Parallel.Test05" ></class>
</classes>
</test>
</suite>
If you want to run 2 classes parallelly
<suite name="Parallel test suite" parallel="classes" thread-count="2">
For classes your testng.xml structure should be like below:-
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Parallel test suite" parallel="classes" thread-count="2">
<test name="Test 1">
<classes>
<class name="com.parallel.TestParallelClassOne"/>
<class name="com.parallel.TestParallelClassTwo"/>
</classes>
</test>
</suite>
Now the thing is you need to add both project classes in different packages in a same project and use my 1 example testng structure and add the attribute as above.
How to run two suites:-
<suite name="allSuites">
<suite-files>
<suite-file path="suite1.xml" />
<suite-file path="suite2.xml" />
...
</suite-files>
</suite>
Hope it will help you :)
Get back to me if still facing any issue :)

Categories