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");
Related
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
I'm trying to get to work a stub for concurrent cross browser test framework using TestNG. BUT seems I cannot get #Parameters from parent class and keep getting
Parameter 'browsername' is required by #Configuration on method setup but has not been marked #Optional or defined
at org.testng.internal.Parameters.createParameters(Parameters.java:155)
at org.testng.internal.Parameters.createParameters(Parameters.java:358)
at org.testng.internal.Parameters.createConfigurationParameters(Parameters.java:86)
at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:199)
at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:138)
at org.testng.internal.TestMethodWorker.invokeBeforeClassMethods(TestMethodWorker.java:175)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:107)
at org.testng.TestRunner.privateRun(TestRunner.java:767)
at org.testng.TestRunner.run(TestRunner.java:617)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:348)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:343)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:305)
at org.testng.SuiteRunner.run(SuiteRunner.java:254)
TestNG.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="1265_Suite" parallel="tests" verbose="2" thread-count="2" preserve-order="true">
<test name="92" parallel="false" preserve-order="true">
<classes>
<class name="com.javacodegeeks.testng.maven.BaseTest"/>
<class name="com.javacodegeeks.testng.maven.ChildTest"/>
<parameter name="browsername" value="chrome"/>
</classes>
</test>
<test name="93" parallel="false" preserve-order="true">
<classes>
<class name="com.javacodegeeks.testng.maven.BaseTest"/>
<class name="com.javacodegeeks.testng.maven.ChildTest"/>
<parameter name="browsername" value="firefox"/>
</classes>
</test>
</suite>
BaseTest
public class BaseTest extends Assert {
protected String browser;
#BeforeClass
#Parameters({"browsername"})
public void setup(String browsername) {
System.err.println("Browser name in #BeforeClass is " + browsername);
this.browser = browsername;
}
}
ChildTest
public class ChildTest extends BaseTest {
#Test
public void test() {
System.out.println(browser);
}
}
I didn't find enough information on how to get this to work so if you have any ideas I would like to hear them.
Already checked but not enough info:
TestNG Annotations in a Superclass
Try again with <parameter> nodes on the <test> nodes (and BaseTest should be useless):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="1265_Suite" parallel="tests" verbose="2" thread-count="2" preserve-order="true">
<test name="92" parallel="false" preserve-order="true">
<parameter name="browsername" value="chrome"/>
<classes>
<!--class name="com.javacodegeeks.testng.maven.BaseTest"/-->
<class name="com.javacodegeeks.testng.maven.ChildTest"/>
</classes>
</test>
<test name="93" parallel="false" preserve-order="true">
<parameter name="browsername" value="firefox"/>
<classes>
<!--class name="com.javacodegeeks.testng.maven.BaseTest"/-->
<class name="com.javacodegeeks.testng.maven.ChildTest"/>
</classes>
</test>
</suite>
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 :)
Not sure where am going wrong, i am trying to run same set of test one after the other on multiple browser.
TestNG.xml
<suite name="Selenium Tests" parallel="false" thread-count="5">
<listeners>
<listener class-name="ww5.listener.Listener" />
</listeners>
<test name="Chrome" preserve-order="true">
<parameter name="browser" value="chrome"/>
<classes>
<class name="ww5.testcases.version.version" ></class>
<class name="ww5.testcases.loginSuite.LoginTest" ></class>
<class name="ww5.testcases.loginSuite.LogoutTest" ></class>
</classes>
</test>
<test name="Firefox" preserve-order="true">
<parameter name="browser" value="firefox"/>
<classes>
<class name="ww5.testcases.version.version" ></class>
<class name="ww5.testcases.loginSuite.LoginTest" ></class>
<class name="ww5.testcases.loginSuite.LogoutTest" ></class>
</classes>
</test>
</suite>
When i run this, all the test are excuted on chrome, how do i make it excute on firefox after it finish excuting on chrome.
OpenBrowser.java
#Parameters ({"browser"})
#BeforeClass
public void launchBrowser(String browser) throws Exception {
//initLogs(this.getClass());
initConfigurations();
if (driver == null) {
DesiredCapabilities cap = null;
if(browser.equalsIgnoreCase("firefox"))
{
cap = DesiredCapabilities.firefox();
cap.setBrowserName("firefox");
//cap.setPlatform(org.openqa.selenium.Platform.WINDOWS);
}
if(browser.equalsIgnoreCase("internet explorer"))
{
cap = DesiredCapabilities.internetExplorer();
cap.setBrowserName("internet explorer");
cap.setPlatform(org.openqa.selenium.Platform.ANY);
}
if(browser.equalsIgnoreCase("chrome"))
{
cap = DesiredCapabilities.chrome();
cap.setBrowserName("chrome");
cap.setPlatform(org.openqa.selenium.Platform.ANY);
}
driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), cap);
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
wait = new WebDriverWait(driver,30);
}
}
Replace <suite name="Selenium Tests" parallel="false" thread-count="5">
with
<suite name="Selenium Tests" parallel="tests" thread-count="2">
All other things seems to be fine. Refer this for more info.
Edit:
I understood your problem incorrectly. The issue that you are not able to run test sequentially is due to if (driver == null). That mean your test will run well first time as driver is null, but after that due to your driver definition it may not be null and hence will not create another capability. So, if you remove it, the tests should run fine.
I am experiencing the following problem. I have set up a grid with 2 nodes, in order to run tests in parallel.My suite.xml file has two groups, one for each node:
<suite name="testSuites" configfailurepolicy="continue" thread-count="2" parallel="tests">
test name="testSuite1" preserve-order="true">
<classes>
<class name="testA1" />
<class name="testB1" />
<class name="testC1" />
</classes>
</test>
<test name="testSuite2" preserve-order="true">
<classes>
<class name="testA2" />
<class name="testB2" />
<class name="testC2" />
</classes>
</test>
Each class, for example testA1 has the following testNG configuration:
#BeforeClass(alwaysRun = true)
public void createInitialData() {
}
#Test(alwaysRun = true, description = "bla bla")
public void testStep_1() throws Exception{
}
#Test(alwaysRun = true, description = "bla bla ", dependsOnMethods ="testStep_1" )
public void testStep_2() {
}
Upon running I noticed that during the execution, the tests are executing in test step wise order, meaning:
testA1-testStep_1, testB1-testStep_1, testC1-testStep_1, testA1-testStep_2, testB1-testStep_2, testC1-testStep_2
whereas it should have been:
testA1-testStep_1, testA1-testStep_2, and then testB1-testStep_1, testB1-testStep_2, testC1-testStep_1, testC1-testStep_2
Any suggestions?
Try to set group-by-instances in your xml
<suite group-by-instances="true">
or
<test group-by-instances="true">
<test name="testSuite2" parallel="false">
Seem also be doing what you need.