Unable To Fetch parameterized value from testNG xml - selenium

This is the testNG.xml File:
This is the day4.java File
]
This is the console Result.
Why I am getting this issue?
I also tried with #optional method but in the that way I am getting the NULL value.

You are not passed any parameter value in the testng.xml file.Your xml file should look like
<suite name="Parameter test Suite" verbose="1">
<!-- This parameter will be passed to every test in this suite -->
<parameter name="suite-param" value="suite level parameter" />
<test name="Home loan">
<classes>
<class name="test">
<methods>
<include name="demo" />
</methods>
</class>
</classes>
</test>
</suite>
Here parameter name and value will be your URL
Few more details about xml file
https://developers.perfectomobile.com/display/TT/TestNG+-User+specified+TestNG+xml+parameters

So you have to make 2 changes.
Your code should look like this:
#Parameter("URL")
#Test
public void webloginHomeloan(#Optional String urlname){
System.out.println("WebloginHome");
System.out.println("Parameterized value is:"+ URL)
}
Add #Optional in parameter as you are not passing any value from String urlname and change "urlname" to "URL"

Related

How to execute multiple test cases using testNG

I want to understand how do we execute multiple test cases using testNg. Suppose my web application consists of 10 pages.Then how do we execute the below test cases.
1) 1st TC- Traversing or navigating to page 1,2,3,4,5&6.
2) 2nd TC- Traversing or navigating to page 1,2,3,8,9&10.
3) 3rd TC- Traversing or navigating to page 1,2,6,7,8.
all pages have corresponding priorities. Page 1 has priority 1, Page 2 has priority 2 etc.
Is it that we need to call related methods(methods defined in each page.) in each #Test annotations.
Thanks!
It seems like you have one #Test annotated method for each page. If they can traverse correctly logically as you have mentioned, then to run them for your test cases , I would remove priorities from TC's and use this xml with preserve-order="true" , so they run in same order. You can add more TC to below in same manner. Have a look at this
Below xml will call methods in that order , you need to make sure they can go to your pages correctly
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="yourSuiteName" >
<test name="1stTC" preserve-order="true">
<classes>
<class name="yourPackage.YourClass" >
<methods>
<include name="method1" />
<include name="method2" />
<include name="method3" />
<include name="method4" />
<include name="method5" />
<include name="method6" />
</methods>
</class>
<classes>
</test>
<test name="2ndTC" preserve-order="true">
<classes>
<class name="yourPackage.YourClass">
<methods>
<include name="method1" />
<include name="method2" />
<include name="method3" />
<include name="method8" />
<include name="method9" />
<include name="method10" />
</methods>
</class>
</classes>
</test>
</suite>
If you have multiple pages then you can have Page object class for each web page. that class can have multiple methods which implemented as operation that could be performed on that page and may return object of next page it is navigating to. Using such objects of Page object classes and their methods, you can design your test method that will be considered as Test case.
E.g.
- for Login page, define Login.java with all the required elements on the page and define method as below
public Homepage loginAction(String Username, String Password){
// write code to perform login opeartion
// it returns Homepage object that you can store in Homepage type variable and you can call other operations of Homepage on that object.
}
Once, you have all the Page object classes are ready to consume, you can write test cases by calling tat methods.
E.g.:
#Test
public void TestCaseOne(){
Login loginpage = new Login();
Homepage homepage = loginpage.loginAction("ABC","XYZ");
homepage.selectAcc(1);
}

How to create testng.xml with following requirements?

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.

Test method not run with sequence in testng

I am using TestNG + WebDriver for my automation project but order of test execution is not working as expected have specified the order for each method below is the method signature and notation
#Test(dependsOnMethods="verifyElementsOnProfileScreen",alwaysRun = true)
public void verifyMySelfProfileVisibility(){
TestSuit the I have using :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="regressionSuite" parallel="none">
<parameter name="ApplicationOpt" value="web"></parameter>
<parameter name="Browser" value="firefox"></parameter>
<test name="Test">
<classes>
<!-- Login Module -->
<class name="Tests.Login.LoginApp"/>
<method>
<include name ="loginUser"></include>
</method>
<!-- Portal Module -->
<class name="Tests.Profile.ProfileModule">
<method>
<include name="verifyElementsOnProfileScreen"></include>
<include name="verifyMySelfProfileVisibility"></include>
</method>
</class>
<class name="Tests.Profile.participantAuditLog">
<method>
<include name="verifyAuditLogForCreateProfileEvent"></include>
<include name="verifyAuditLogForUpdateContactInfoEvnet"></include>
<include name="verifyAuditLogForUpdatePrivacyDirective"></include>
</method>
</class>
</classes>
</test> <!-- Test -->
</suite> <!-- regressionSuite -->
Do you mean Classes which specified in testng.xml file not executing in specified order.. then please use preserve-order= "true"
<suite name="MySuite" preserve-order= "true">
<test name="MyTest">
If you want to specify order of methods execution in Class then use priority
#Test( priority = 1 )
group-by-instances="true" also useful if you face situation like execution order of priority methods of different classes are not as expected..
<suite thread-count="2" verbose="10" name="testSuite" parallel="tests">
<test verbose="2" name="MytestCase" group-by-instances="true">
Thank You,
Murali

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.

Maven issue:Regarding Testng

I have a module A which runs through pom.xml and accesses a testng.xml which in turn calls a specific class.This class displays a list of things for the user to choose from.
I am taking the user value through bufferRead.The bufferRead does not detect the value entered by the User.
ie
Enter the test u want to run
1.Test1
2.Test2
3.Test3
1
(control never goes to the next line)
There goes my pom.xml
<suiteXmlFiles>
<suiteXmlFile>testng.xml</suiteXmlFile>
</suiteXmlFiles>`
This is my testng.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?><suite allow-return-values="false" configfailurepolicy="skip" data-provider-thread-count="10" group-by-instances="false" junit="false" name="Suite" parallel="false" preserve-order="true" skipfailedinvocationcounts="false" thread-count="5">
<test allow-return-values="false" group-by-instances="false" junit="false" name="Test" preserve-order="true" skipfailedinvocationcounts="false">
<classes>
<class name="com.org.Console1"<methods>
<include name="main" />
</methods>
</class>
</classes>
</test> <!-- Test -->
This is my java code that runs
System.out.println("Which tests do you want to run");
String input = bufferRead.readLine();