How to create testng.xml with following requirements? - selenium

Run tests in three browsers (chrome, firefox and ie) parallely. Each browser should open 2 instances. In total, on triggering testng.xml , 6 browser instances should be opened.
<suite thread-count=3 parallel="tests">
<test>
for firefox
</test>
<test>
for chrome
</test>
<test>
for ie
</test>
</suite>
Please help me!

In your TestNG.xml file , add a parameter for specifying browser type.
<test>
<parameter name="browser" value="firefox">
<parameter name="username" value="testuser"/>
<parameter name="password" value="testpassword"/>
<classes>
<class name="com.parameterization.TestParameters" />
</classes>
</test>
<test>
<parameter name="browser" value="chrome">
<parameter name="username" value="testuser"/>
<parameter name="password" value="testpassword"/>
<classes>
<class name="com.parameterization.TestParameters" />
</classes>
</test>
<test>
<parameter name="browser" value="ie">
<parameter name="username" value="testuser"/>
<parameter name="password" value="testpassword"/>
<classes>
<class name="com.parameterization.TestParameters" />
</classes>
</test>
</suite>
In your test class receive these parameters and create a webdriver according to the desired capabilities.
package com.parameterization;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
public class TestParameters {
#Parameters({ "browser", "username", "password" })
#Test
public void testCaseOne(String browser,String username, String password) {
System.out.println("browser passed as :- " + browser);
createWebDriver(browser);
loginToApplicationOne(username,password);
}
#Parameters({ "browser", "username", "password" })
#Test
public void testCaseTwo(String browser, String username, String password) {
createWebDriver(browser);
loginToApplicationTwo(username,password);
}
}
As you have set thread-count to 3 and your requirement is to launch 2 browser instances in each test block. You have to refactor your test classes in the above style so that each method block create its isolated driver instance. Thus a total of 6 browsers would be launched.

There is no clean way to do this through xml just workarounds.
You can add the invocationCount to the #Test annotation for the test you want to repeat. Refer to link for more details.
Also you could create a duplicate of the xml file and run them as parallel suites using -suitethreadpoolsize as argument. Also pass in both the xml files as argument. Refer to link for doc.
Plus as suggested in the answers before, copying the tests multiple times in same xml.

Related

How to launch & use separate browser for each test method inside a class

I have the below scenario
All the 3 tests run, but they are sharing only 1 browser. I have all the common methods for all the clicks etc in a Base class.
I want each of the test method -method1/2/3 to launch different browser & work,
Can somebody help?
Class A extends BaseTest{
#BeforeMethod(){
initDriver();// it does setdriver & getDriver is used across
}
public void doStuff(){
...
}
#Test
public void method1(){
doStuff()
}
#Test
public void method2(){
doStuff()
}
#Test
public void method3(){
doStuff()
}
}
You can use TestNG.xml to parameterized and control your execution as below. Here we ahve created 3 different tests , each one of them is parameterized with browser type variable and running one of your #test method.
TestNG.XML
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
<test name="TestChrome">
<parameter name="browser" value="chrome"/>
<classes>
<class name ="<Full path to your Test class>" />
<methods>
<include name="method1" />
</methods>
</classes>
</test>
<test name="TestForefox">
<parameter name="browser" value="firefox"/>
<classes>
<class name ="<Full path to your Test class>" />
<methods>
<include name="method2" />
</methods>
</classes>
</test>
<test name="TestIE">
<parameter name="browser" value="edge"/>
<classes>
<class name ="<Full path to your Test class>" />
<methods>
<include name="method3" />
</methods>
</classes>
</test>
</suite>
Get the browser type parameter in your #BeforeMethod.
#Parameters ({"browser"})
#BeforeMethod(){
initDriver(browser);/* it does setdriver & getDriver is used across. Passing browser name
to initDriver method.*/
}
Now in initDriver() method ( wherever you have implemented it), set driver based on your browser type. Something similar to below:
public void initDriver(String browser) throws Exception{
if(browser.equalsIgnoreCase("firefox")){
System.setProperty("webdriver.gecko.driver", ".\\geckodriver.exe");
driver = new FirefoxDriver();
}
else if(browser.equalsIgnoreCase("chrome")){
System.setProperty("webdriver.chrome.driver",".\\chromedriver.exe");
driver = new ChromeDriver();
}
else if(browser.equalsIgnoreCase("Edge")){
System.setProperty("webdriver.edge.driver",".\\MicrosoftWebDriver.exe");
driver = new EdgeDriver();
}
else{
throw new Exception("Browser is not correct");
}
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.window().maximize();
}
Note: Using include/exclude tag in TestNg.xml file you can run/ignore any #Test methods inside a test.

How to run test cases in different Java classes in a new window every time using TestNG and Selenium

I have 15 test methods in 3 Java classes (Selenium Script). I want to run each Test class with new window. I am using TestNg framework.
Here is the code of TestNG:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Fanfight Test" thread-count="10" parallel="methods">
<listeners>
<listener class-name="com.fanfight.test_case.ListenerClass">
</listener>
</listeners>
<test name="User Login" parallel="false">
<classes>
<class name="com.fanfight.test_case.UserLogin"></class>
</classes>
</test>
<test name="Contest Creation" parallel="false" >
<classes>
<class name="com.fanfight.test_case.ContestCreation"></class>
</classes>
</test>
<test name="User Profile Test" parallel="false" >
<classes>
<class name="com.fanfight.test_case.UserProfileTest"></class>
</classes>
</test>
<test name="Menu Bar Test" parallel="false">
<classes>
<class name="com.fanfight.test_case.MenuBarTest">
</class>
</classes>
</test>
<test name="Home Page Elements" parallel="false" >
<classes>
<class name="com.fanfight.test_case.HomePageElementTest"></class>
</classes>
</test>
</suite>
Without using parallel="false" my script is running in alphabetical order due to which selenium unable to find the path and execution got stuck.
Also please suggest how to make execution continue even after getting an exception during execution.
Add a setup and tear down method in each of the 3 test classes. The setup method should launch the browser and teardown method should close that browser instance.
class TestOne {
WebDriver driver;
#BeforeClass
public void setup(){
driver = new ChromeDriver();
}
#Test
public void testCase1(){
}
//.... Other test methods
#AfterClass
public void tearDown(){
driver.quit();
}
You can also create a parent class having just the setup and tear down methods , pseudo coded above. All 3 of your test class shall extend this parent class. It will be an optimised approach as the driver instantiation and destruction is now centralised to a single class.
And finally , change the parallel attribute in the suite tag of your testNG xml, in order to make them run parallel.
<suite name="Fanfight Test" thread-count="10" parallel="classes">

Is it posible to run feature cucumber in parallel in different browser

I'm working in a big project, i want to run eature cucumber in parallel in different browser
I have the featuren the step definition ? the webdriverfactory and the shared preferences.
I have this method in webfactory and it works and i write the testng.xml
public WebDriver driver;
public static WebDriver get() {
WebDriver driver = null ;
System.setProperty("webdriver.chrome.driver","D:\\Drive\\chromedriver_win32\\chromedriver.exe");
driver= new ChromeDriver();
return(driver);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="SuiteSopraHR" parallel="tests">
<test name="testie">
<!-- <parameter name="myBrowser" value="ie" /> -->
<classes>
<class name="com.driver.WebDriverFactory"/>
</classes>
</test> <!-- Test -->
<test name="testchrome">
<!-- <parameter name="myBrowser" value="chrome" /> -->
<classes>
<class name="com.driver.WebDriverFactory"/>
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
I don't know how to change the other method because it didn't has any parameter to pass and it return a web driver.
when I have changed all the other method in other classes have a problem with it
any suggestion please.
and is the cucumber-jvm can run feature in parallel in different browser ??? or in console ???
You can indeed run Cucumber features and scenarios in parallel using Courgette-JVM
When you run your tests, you can set a System property that would target the browser you wish to use in parallel.
Another useful library to manage your driver binaries is WebDriver Binary Downloader
You can then specify the browser to use at runtime using:
System.setProperty("browser", "chrome");
or
VM option -Dbrowser="chrome"
private WebDriver driver;
public void createDriver() {
final String browser = System.getProperty("browser", "chrome").toLowerCase();
switch (browser) {
case "chrome":
WebDriverBinaryDownloader.create().downloadLatestBinaryAndConfigure(BrowserType.CHROME);
driver = new ChromeDriver();
case "firefox":
WebDriverBinaryDownloader.create().downloadLatestBinaryAndConfigure(BrowserType.FIREFOX);
driver = new FirefoxDriver();
default:
throw new RuntimeException("Invalid browser specified!");
}
}
We are using QAF-Gherkin-client, where you can configure it using one or more xml test nodes. You can run scenarios in parallel as well. You don't need to write any code for driver management or other functional testing common needs.
<suite name="AUT Test Automation" verbose="0" parallel="methods">
<test name="Tests on chrome">
<parameter name="driver.name" value="chromeDriver"/>
<classes>
<class name="com.qmetry.qaf.automation.step.client.gherkin.GherkinScenarioFactory" />
</classes>
</test>
<test name="Tests FF">
<parameter name="driver.name" value="firefoxDriver"/>
<classes>
<class name="com.qmetry.qaf.automation.step.client.gherkin.GherkinScenarioFactory" />
</classes>
</test>
</suite>
I think, you need to add switch construction in your method and parameter - type of browser from testng.xml.
Also, as I know, parallel execution will work only with a non-static Driver.

TestNG DataProvider reading test data from the testng.xml config file?

Is it possible for a TestNG DataProvider to read test data from the testng.xml config file? Or is this unrealistic for some reason? I would like to be able to read test data from that file at the suite level and class level.
So, given a testing.xml file like this (which I am unsure is realistic or not), how would I do this? I have written a DataProvider using XStream (or Jackson) before and so I am well versed in my own custom .xml format, but sticking to the strict format of the testing.xml is where I am worried about this.
The following testing.xml is obvious invalid but I am just trying to show the kind of thing I would like to do:
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="TestAll">
<parameter name="hubUrl" value="http://localhost:4444/wd/hub"/>
<parameter name="reportFile" value="CustomReport.html"/>
<test name="etsy">
<parameter name="reportFile" value="CustomReport.html"/>
<classes>
<class name="qa.examples.suite.TestSearch">
<parameter name="appUrl" value="http://etsy.com" type="java.lang.String"/>
<parameter name="browser" value="Firefox" type="java.lang.String"/>
<parameter name="testEnabled" value="true" type="java.lang.Boolean"/>
<methods>
<include name="testEtsySearch"/>
<tests>
<test>
<parameter name="testNum" value="1" type="java.lang.Integer"/>
<parameter name="searchTerm" value="cell phone" type="java.lang.String"/>
<parameter name="searchTerm" value="batteries" type="java.lang.String"/>
</test>
<test>
<parameter name="testNum" value="2" type="java.lang.Integer"/>
<parameter name="searchTerm" value="buttons" type="java.lang.String"/>
<parameter name="searchTerm" value="metal" type="java.lang.String"/>
</test>
</tests>
</include>
</methods>
</class>
<class name="qa.examples.suite.TestFilters" />
</classes>
</test>
</suite>
So, is something like this possible? If so, how would you do it?
Try to pass ITestContext as a data provider parameter.
Something like:
#DataProvider(name = "DataProvider")
public static Object[][] Provider(ITestContext context) throws Exception
{
String dataFile = context.getCurrentXmlTest().getParameter("dataFile");
}
Suite xml
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="suite">
<parameter name="param1" value="val1"/>
<test name="test">
<parameter name="param2" value="val2"/>
<classes>
<class name="test.TestClass1" />
</classes>
</test>
</suite>
test class
package test;
import java.util.Map;
import org.testng.ITestContext;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class TestClass1 {
#DataProvider(name="Provider")
public Object[][] provider(ITestContext context)
{
Map<String, String> testParams = context.getCurrentXmlTest().getLocalParameters();
Map<String, String> suiteParams=context.getCurrentXmlTest().getSuite().getParameters();
return new Object[][]{{suiteParams.get("param1"), testParams.get("param2")}};
}
#Test(dataProvider="Provider")
public void test1(String param1, String param2)
{
System.out.println("Param1: " + param1);
System.out.println("Param2: " + param2);
}
}
Output
[TestNG] Running:
/home/nightmare/workspace/test/suite.xml
Param1: val1
Param2: val2
===============================================
suite
Total tests run: 1, Failures: 0, Skips: 0
===============================================
I am currently passing only Suite Level Parameters from my XML. This is how I would do it -
I would create a class - readParamsFromXML.
#Parameters( { "suiteParam1", "suiteParam2" } )
#BeforeSuite
public void getSuiteLevelParamsFromXML(
#Optional("defaultValueForSuiteParam1")String SuiteParam1,
#Optional("defaultValueForSuiteParam2")String SuiteParam2 ) {
<Some Logic here based on the params passed>
}
I would extend a similar logic to read params at Test level & Method level by creating methods like - getTestLevelParamsFromXML & getMethodLevelParamsFromXML. I would add annotations like #BeforeClass & #BeforeMethod respectively for the above methods.
Now, all my test cases should extend readParamsFromXML class. This way - suite, test & class level parameters passed from XML could be available in test methods
Might not be the best way to get things done. But works perfectly for me.

How to run parallel Test case in Selenium + TestNG

I have a test script as follows, what I need to know is how I can make it to run in different browser at same time but with different test data,
Exactly what I want is I want parallel instance of Test Case one in Firefox and other in Internet Explorer, but again I want to use different data for it
Eg:
-Firefox with 'username1' and 'password1'
-Internet Explorer 'username2' and 'password2'
it is like logging into GMAIL with different usernames and password parallel in different browser but not in sequence.
Test Case :
public class Gmail
{
private WebDriver driver;
#BeforeClass
public void setup()
{
driver = new FirefoxDriver();
driver.get("http://www.gmail.com");
}
#Test
public void search()
{
WebElement element = driver.findElement(By.name("username"));
element.sendKeys("username");
WebElement element2 = driver.findElement(By.name("pass"));
element2.sendKeys("password");
element2.submit();
}
#Test
public void compose()
{
driver.findElement(By.name("compose")).click();
}
#AfterClass
public void exit()
{
driver.quit();
}
}
Please give your suggestion would help in my project.
Steps to do this:
Pass the required values as parameters in testNG.xml - in your case you need browserName, userName & password.
Create 2 separate "test" tag in testNG.xml with different userName & password parameter
<test name="Test on FF">
<parameter name="browserName" value="Firefox" />
<parameter name="userName" value="user1" />
<parameter name="password" value="pass1" />
<classes>
<class>name="Gmail"</class>
</classes>
</test>
<test name="Test on IE">
<parameter name="browserName" value="IE" />
<parameter name="userName" value="user2" />
<parameter name="password" value="pass2" />
<classes>
<class>name="Gmail"</class>
</classes>
</test>
Define "suite" tag as <suite thread-count="2" name="Suite" parallel="tests">
Access and use those in your #Test method by #Parameters ({"browserName","userName","password"}) and instantiate corresponding driver
If you have huge set of data, you can externalize it. Move it to an excel, yaml or whichever format you are comfortable with. Use that as an input to your #DataProvider method. In the #DataProvider, read all values from your chosen format and return. In your testmethods specify the dataprovider method. Read more about dataproviders here. Give the excel sheet in your parameter values. You can run the dataprovider parallelly by setting the
parallel to true. Make sure your driver instances are either Threadlocal values or are instantiated for each method else parallel runs may lead to failures.
I found the solution with working code on http://www.ufthelp.com/2014/12/Parallel-execution-tests-in-testNG-eclipse.html
XML File will look like this
<suite name="Suite" parallel="tests" thread-count="2">
<test name="Run in Firefox">
<parameter name="browser" value="firefox"></parameter>
<parameter name="userName" value="Test1"></parameter>
<parameter name="Password" value="Pwd1"></parameter>
<classes>
<class name="srcTest.ParallelTesting"/>
</classes>
</test>
<test name="Run in chrome">
<parameter name="browser" value="chrome"></parameter>
<parameter name="userName" value="Test2"></parameter>
<parameter name="Password" value="Pwd2"></parameter>
<classes>
<class name="srcTest.ParallelTesting"/>
</classes>
</test>
</suite>
Java Code:-
#Test
#Parameters({"userName","Password"})
public void login(String userName,String Password){
--Your Code--
}
#BeforeClass<br/>
#Parameters({"browser"})
public void BeforeClass(String browser) throws Exception {
--Your code--
}