I am having trouble reading parameter values from testng.xml inside a testng testcase in Eclipse IDE. I have browser initiated from BeforeClass and at #TEST method ,parameter values are coming as "NULL"...and it asks me to define my #Test parameters as Optional..
MyJavacode
public class headerValidation extends init {
WebDriver driver;
#BeforeClass
public void beforeClass() {
driver = initBrowser(BrowserType.FIREFOX, "http://www.abc123.com/");
}
#Test
#Parameters(value = { "loginID", "PasswordKey", "testURL" } )
public void testLogin(String loginID, String PasswordKey, String testURL) throws Exception {
try {
driver.get(testURL);
driver.findElement(By.id("login-b")).click();
driver.findElement(By.id("login_e")).sendKeys(loginID);
driver.findElement(By.id("login_p")).sendKeys(PasswordKey);
driver.findElement(By.name("submit")).click();
}//try
catch (Exception e) {
e.printStackTrace();
}//catch
My Testng XML file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite" parallel="none">
<test name="Test">
<parameter name="loginID" value="emailadd#add2.com"></parameter>
<parameter name="PasswordKey" value="21232131"></parameter>
<parameter name="testURL" value="www.abctest.com"></parameter>
<classes>
<class name="org.pa.qa.headerValidation"/>
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
Am i missing something here?
If you right click on the file and run as testng test, the testng xml is not picked up by default, which explains why the parameters are not being picked up.
Two solutions :
Right click on the suite xml and trigger with Run as ->testng suite
OR
Go to Project->Properties->Testng-> Set this xml as your template xml and then you can run as testng test
Related
I am running tests via selenium grid. I have been getting aforementioned error.
Following are the solutions I tried
Tried running tests from testng.xml
Set the template for testng.xml from testng properties
The error persisted
My testg file is as follows
<suite name="TestSuite" thread-count="2" parallel="tests">
<listeners>
<listener class-name="com.hrmapp.orangehrm.Tests.ExtentListener"></listener>
</listeners>
<test name="tests">
<parameter name="browser" value="chrome"></parameter>
<classes>
<class name="com.hrmapp.orangehrm.Tests.OrangeHRMTests"></class>
</classes>
</test>
<test name="tests2">
<parameter name="browser" value="firefox"></parameter>
<classes>
<class name="com.hrmapp.orangehrm.Tests.OrangeHRMTests"></class>
</classes>
</test>
</suite>
My java class looks like this
#Parameters("{browser}")
#BeforeClass
public void setup(String browser) throws IOException {
System.out.println(browser);
launch(browser);
}
public static void launch(String browser) throws MalformedURLException{
prop=PropertyReader.readData();
setDriver(browser);
// setDriver(prop.getProperty("browser"));
getDriver().manage().window().maximize();
getDriver().get(prop.getProperty("url"));
}
Thanks for your time
Try to pass browser parameters Before test, since your setup value for test in .xml.
#BeforeTest(alwaysTrue = true)
#Parameters("{browser}")
public void setup(String browser) throws IOException {
System.out.println(browser);
launch(browser);
}
Let me know if not gonna work, I'll take a look.
This issue got resolved after I corrected the syntax of parameters
The correct syntax is
Parameter({"browser"})
and
not
Parameter("{browser}")
Can you please try to execute below code and let us know if it works
#Parameters("browser")
#BeforeClass
public void setup(String browser) throws IOException {
System.out.println(browser);
launch(browser);
}
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.
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">
Hi I am seeing this error, please help
Parameter 'Visit' is required by #Test on method searchByVisitNo but has not been marked #Optional or defined.
I don't know why is there a need to mark it optional when it is defined in testng xml file
Here is the entire code I used
<suite name="Suite" parallel="tests">
<test name="SearchByVisit">
<parameter name="Visit" value="123456"/>
<classes>
<class name="abc"/>
</classes>
</test>
</suite>
#Parameters({"Visit"})
#Test(priority=3)
public void searchByVisitNo(String VisitNumber)throws InterruptedException
{
searchByVisit(VisitNumber);
}
public void searchByVisit(String Visit) throws InterruptedException
{
WebDriverWait wait = new WebDriverWait(driver, 20);
WebElement element = wait.until(
ExpectedConditions.visibilityOfElementLocated(By.id("search-input"))
);
element.sendKeys(Visit);
clickSearch();
}
You are passing paramter <parameter name="Visit" value="123456"/> in your .xml file and you directly running your TestNG class. So it's not getting that parameter while compiling .
So you need to run your xml suite to provide a valid parameter to your TestNG class.
You are getting this error as you are directly running this class. You should run your TestNG XML file.
Steps which you can follow:
Create a test suite.
Specify class and method name(Class name should be packageName.className)
Specify the parameters which should be used for a method.
Run the test suite.
Looks like you are directly trying to run the class hence it is showing that exception.
In your TestNG.xml file, you need to provide your test class name and in class name you need to provide the class name along with package. That would resolve the issue!
Consider below example for reference :
If the test class name is Testclass and it's under package com.testpackage, then your testNG.xml file would look like below:
<suite name="Suite" parallel="tests">
<test name="Testclass">
<parameter name="Visit" value="123456"/>
<classes>
<class name="com.testpackage.Testclass"/>
</classes>
</test>
</suite>
Even I was facing the same issue the problem simple ..
In Testng XML I was passing the parameters in the day1 code instead of day4
Pass these all parameter to correct test cases folder in testng XML
Consider belows
Day1 code and Day4 code two are there
In Testng xml passing the parameter in day4 instead of day1 will throw this error
Day 1
package test2;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
public class Day1 {
#Parameters({"URL"}) //Only to Particular test method only
#Test
public void test11(String urlname)
{
System.out.println(urlname);
System.out.println("Test case 11 in Day1");
}
#Test
public void test12()
{
System.out.println("Test case 12 in Day1");
}
#Test
public void test13()
{
System.out.println("Test case 13 in Day1\n");
}
}
Day4
package test2;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
public class Day4 {
#Parameters({"URL","API/username"})
#Test
public void test41(String urlname, String name)
{
System.out.println(urlname);
System.out.println("Test case 41 in Day4");
System.out.println(name);
}
#Test
public void test42()
{
System.out.println("Test case 42 in Day4");
}
}
XML ERROR
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
<parameter name = "URL" value = "https://www.youtube.com"/>
<**test name = "Day2Testcase">
<parameter name = "URL" value = "day2test2.com"/>
<parameter name = "API/username" value = "12345"/>**
<classes>
<class name = "test2.Day1">
</class>
</classes>
</test>
<test name = "Day4Testcase">
<parameter name = "URL" value = "day4test2.com"/>
<classes>
<class name = "test2.Day4">
</class>
</classes>
</test>
ERROR
[Utils] [ERROR] [Error] org.testng.TestNGException: Parameter
'API/username' is required by #Test on method test41 but has
not been marked #Optional or defined in F:\Selenium WebDriver with
Java -Basics to Advanced+Frameworks by Rahul
Shetty\Workspace\TestNG_Tutorial\testng.xml
Corrected the XML
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
<test name = "Day2Testcase">
<parameter name = "URL" value = "day2test2.com"/>
<classes>
<class name = "test2.Day1">
</class>
</classes>
</test>
<test name = "Day4Testcase">
<parameter name = "URL" value = "day4test2.com"/>
<parameter name = "username" value = "12345"/>
<classes>
<class name = "test2.Day4">
</class>
</classes>
</test>
</suite> <!-- Suite -->
Step1:- In Testng.xml define class name as: "packagname.abc"
Step2:- Now right click on testng.xml and Run As-> TestNG Suite.
Note: If you directly run testng class "abc.java" with Testng Test command it will not pic parameters value from testng.xml so you will have to run the testng.xml instead of running testNG class "abc.java" as TestNG Test
You should try updating your pom with below. Simply add the below in your pom and then execute.
Add it just above dependencies tag.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20.1</version>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>testng.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>
</plugins>
</build>
Mention below line at the start of your XML file:
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
You need to add #Optional("Abc") in your method, which specifies that the current parameter is optional. TestNG will pass in a specified default value, or null if none is specified.
Try doing public void searchByVisit(#Optional("Abc") String Visit) throws InterruptedException
Are you using a Maven repo? Try running your pom.xml as Maven clean and then Maven test. This worked for me
My mistake was I was passing parameter keyword as "Parameter" (P-capital)
So, I faced the same issue while passing the parameter so I added #Optional to my function parameter.
#Test(priority = 2)
#Parameters("myName")
public void LoginAccountProcess(#Optional("Abc")String name) throws
FileNotFoundException, IOException, InterruptedException {
System.out.println("Name of th login Id is ==>"+name);
WebDriver chromeDriverObj=reusableComp.getLoadDriver();
chromeDriverObj.get(reusableComp.getUrl());
Eclipse Editor provides running from both XML and directly from the test file. Try that or run with XML file by using 'mvn test' command.
Seems the issue is with using curly-braces.
I had tried with below snippet:
#Parameters({"browser"})
#BeforeMethod
public void setUp(String browser){
if(browser.equalsIgnoreCase("Mozilla Firefox")){
driver = new FirefoxDriver();
}
was getting the below error:
Parameter '{browser}' is required by BeforeMethod on method setUp but has not been marked #Optional or defined
It started working after removing the curly-braces as below:
#Parameters("browser")
After Opening browser, no URL is being passed and it last with Error which says
"Parameter 'browser' is required by BeforeTest on method setup but has not been marked #Optional or defined
in C:\Users\hassan.anwer\IdeaProjects\CRBTesting\testing.xml"
I am using testNG with Selenium webdriver2.0.
In my testNG.xml I have
<suite data-provider-thread-count="2" name="selenium FrontEnd Test" parallel="false" skipfailedinvocationCounts="false" thread-count="2">
<parameter name="config_file" value="src/test/resources/config.properties/"/>
<test annotations="JDK" junit="false" name="CarInsurance Sanity Test" skipfailedinvocationCounts="false" verbose="2">
<parameter name="config-file" value="src/test/resources/config.properties/"/>
<groups>
<run>
<include name="abstract"/>
<include name="Sanity"/>
</run>
</groups>
<classes>
</classes>
</test>
</suite>
In java file
#BeforeSuite(groups = { "abstract" } )
#Parameters(value = { "config-file" })
public void initFramework(String configfile) throws Exception
{
Reporter.log("Invoked init Method \n",true);
Properties p = new Properties();
FileInputStream conf = new FileInputStream(configfile);
p.load(conf);
siteurl = p.getProperty("BASEURL");
browser = p.getProperty("BROWSER");
browserloc = p.getProperty("BROWSERLOC");
}
Getting error as
AILED CONFIGURATION: #BeforeSuite initFramework
org.testng.TestNGException:
Parameter 'config-file' is required by #Configuration on method initFramework
but has not been marked #Optional or defined in
How to use #Parameters for resource file?
Looks like your config-file parameter is not defined at the <suite> level. There are several ways to solve this:
1. Make sure the <parameter> element is defined within <suite> tag but outside of any <test>:
<suite name="Suite1" >
<parameter name="config-file" value="src/test/resources/config.properties/" />
<test name="Test1" >
<!-- not here -->
</test>
</suite>
2. If you want to have the default value for the parameter in the Java code despite the fact it is specified in testng.xml or not, you can add #Optional annotation to the method parameter:
#BeforeSuite
#Parameters( {"config-file"} )
public void initFramework(#Optional("src/test/resources/config.properties/") String configfile) {
//method implementation here
}
EDIT (based on posted testng.xml):
Option 1:
<suite>
<parameter name="config-file" value="src/test/resources/config.properties/"/>
<test >
<groups>
<run>
<include name="abstract"/>
<include name="Sanity"/>
</run>
</groups>
<classes>
<!--put classes here -->
</classes>
</test>
</suite>
Option 2:
#BeforeTest
#Parameters( {"config-file"} )
public void initFramework(#Optional("src/test/resources/config.properties/") String configfile) {
//method implementation here
}
In any case, I would recommend not having two parameters with almost identical names, identical values, and different scope.
You want to use #Parameter in #BeforeSuite. Suite level parameters are parsed once the suite begins execution and I believe TestNG invokes #BeforeSuite even before the suite is processed:
Here is a workaround: add ITestContext in method parameters to inject
#BeforeSuite(groups = { "abstract" } )
#Parameters({ "configFile" })
public void initFramework(ITestContext context, String configFile) throws Exception {