Can a Parameterized method be called in a TestNG XML Suite? - java

I have a parameterized method(readConfig_1(String path)) in a class which I need to run before the tests in a TestNG Suite. Is there a way that I can call this method and define the parameter for the same in the TestNG.xml file?
Here's the Parameterized Method, I have written which actually needs a path to where the XML file is stored.
public static void readConfig_1(String configXmlPath)
{
browser = CoreLib.fGetNodeText(configXmlPath, "config",
"browser");
env = CoreLib.fGetNodeText(configXmlPath, "config", "env");
release = CoreLib.fGetNodeText(configXmlPath, "config", "release");
serverName = CoreLib.fGetNodeText(configXmlPath, env,
"serverName");
host = CoreLib.fGetNodeText(configXmlPath, env, "host");
userName = CoreLib.fGetNodeText(configXmlPath, env, "userName");
passWord = CoreLib.fGetNodeText(configXmlPath, env, "passWord");
portNumber = CoreLib.fGetNodeText(configXmlPath, env,
"portNumber");
schema = CoreLib.fGetNodeText(configXmlPath, env, "schema");
url = CoreLib.fGetNodeText(configXmlPath, env, "url");
screenShotForPass=CoreLib.fGetNodeText(configXmlPath, env, "SCreenShotForPass");
screenShotForFail=CoreLib.fGetNodeText(configXmlPath, env, "SCreenShotForFail");
CoreLib.LOGGER.info("****************************************************");
CoreLib.LOGGER.info(" Configuration Details ");
CoreLib.LOGGER.info("****************************************************");
CoreLib.LOGGER.info("Browser ::" + browser);
CoreLib.LOGGER.info("env ::" + env);
CoreLib.LOGGER.info("serverName ::" + serverName);
CoreLib.LOGGER.info("host ::" + host);
CoreLib.LOGGER.info("userName ::" + userName);
CoreLib.LOGGER.info("passWord ::" + passWord);
CoreLib.LOGGER.info("portNumber ::" + portNumber);
CoreLib.LOGGER.info("schema ::" + schema);
CoreLib.LOGGER.info("url::" + url);
CoreLib.LOGGER.info("ScreenSnapShotForPass::"+screenShotForPass );
CoreLib.LOGGER.info("ScreenSnapShotForFail::"+screenShotForFail );
}
In this TestNG Suite seen below, I need to call the above method passing a parameter to it before it can go ahead and run the tests written in the other classes.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Smoke Suite" parallel="false" preserve-order="true">
<listeners>
<listener class-name="com.healthcare.reports.MyListener"></listener>
</listeners>
<test name="XYZ Tests">
<classes>
<class name="com.healthcare.utility.Config">
<methods>
<include name="readConfig_1"></include>
</methods>
</class>
<class name="com.healthcare.businessLib.xyz.AddUserTests" />
</classes>
</test>
</suite>
By this I intend to restrict a TestNG Suite to read a particular Config.XML file which will have it's own values such as Env, URL, browser etc., set before the tests can be executed. Is there a way I can achieve this?
----Added 11/24/2017-----
---- I thought adding the readConfig_1 to a #BeforeClass annotation would resolve the problem. But there's more to it-----
My Listener Class has **#onStart** annotation which needs the config file to be run on the start of the Suite. As you see below my Listener Class has the variables release_1 coming from Config file.
public class MyListener implements ITestListener, ISuiteListener {
// This belongs to ISuiteListener and will execute before the Suite start
ReportLib report=new ReportLib();
#Override
public void onStart(ISuite arg0) {
Config.readConfig_1(configXlsPath);
ExportTestResults export = new ExportTestResults();
export.exportExcelHeader(Config.release_1);
CoreLib.fCreateLogger(Config.release_1);
}
But if I put it in #BeforeClass in a TestClass these variables(Config.release_1) are returning null as they would be running before the test class. So I need the readconfig_1 to run before or with the Listener class and unable to add a parameter to the onStart(ISuite arg0).
Tried a few things by :
Running the readConfig_1() in the TestNG.XML as the first method even before the listener class could be called.
putting a #BeforeClass annotation in the Listener class with readConfig_1() method parameterized in it- hoping that the readConfig would be called before the onStart() is executed.
public class MyListener2 implements ITestListener, ISuiteListener {
ReportLib report=new ReportLib();
#BeforeClass
#Parameters("configXlsPath")
public void beforeSuite(String configXlsPath)
{
Config.readConfig_1(configXlsPath);
System.out.println("In Before Class(Listener_2)"+ Config.release_1);
}
#Override
public void onStart(ISuite arg0) {
ExportTestResults export = new ExportTestResults();
System.out.println("In onStart(Listener_2)"+ Config.release_1);
export.exportExcelHeader(Config.release_1);
CoreLib.fCreateLogger(Config.release_1);
}
}
But none worked.
Is there a way around this now?
Thanks in advance.

Yes, you can do this. Firstly, add #Parameters("configXmlPath") annotation to your test class. configXmlPath parameter must also be defined in testng.xml file like <parameter name = "configXmlPath" value="Whateverthevalueis"/> this. Here is an example.
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
public class YourTest {
#Test
#Parameters("configXmlPath")
public void test1(String configXmlPath) {
System.out.println("Parameterized value is : " + configXmlPath);
}
}
Then, in your testng.xml define parameter like this:
<?xml version = "1.0" encoding = "UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name = "Suite1">
<test name = "test1">
<parameter name = "configXmlPath" value="Whateverthevalueis"/>
<classes>
<class name = "YourTest" />
</classes>
</test>
</suite>

In your java method , use #BeforeClass and #Parameters annotation ,
#BeforeClass
#Parameters({"configXlsPath"})
public static void readConfig_1(#Optional("addaDefaultPathValue") String configXlsPath)
In your xml , add a parameter tag after tests tag.
<test name="Purchaser Tests">
<parameter name="configXlsPath" value="target/path/to/xmlFile">

You need to define your Parameterized Method under #BeforeClass annotations and should be inside the test class or inherited from other class. I was also dealing with the same issue and resolved this in the below ways:
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
public class AddUserTests {
#BeforeClass(alwaysRun = true)
#Parameters("configXmlPath")
public void readConfig_1(String configXmlPath){
System.out.println("File path : "+ configXmlPath);
/*
You can use the configXmlPath value to
your code that goes here
*/
}
#Test
public void test_1(){
//Test Code
}
#Test
public void test_2(){
//Test Code
}
}
You need to define and set your parameter value in the xml file like
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Smoke Suite" parallel="false" preserve-order="true">
<listeners>
<listener class-name="com.healthcare.reports.MyListener"></listener>
</listeners>
<test name="XYZ Tests">
<parameter name="configXmlPath" value="USE_ABSOLUTE_PATH_HERE"/>
<classes>
<class name="com.healthcare.businessLib.xyz.AddUserTests" />
</classes>
</test>
</suite>
Please use the absolute path [i.e,C://Config.XML] of the config file instead of USE_ABSOLUTE_PATH_HERE

Related

Parallel execution using TestNg Selenium in a POM framework overwriting the data object class

I am trying to run two test classes in parallel both are using data providers pointing to different excel sheets. Sequentially it runs fine, but while running it in parallel it seems like the test object class which is holding all the test data is getting overwritten. Below is the data provider
Class 1
#DataProvider(name = "tradeData" )
public Object[][] createMessage() {
return ExcelUtils
.getDataFromExcelSheet("TestSheet1", LOADTESTDATAPROVIDER);
}}
Class 2
#DataProvider(name = "tradeData")
public Object[][] createMessage() {
return ExcelUtils
.getDataFromExcelSheet("TestSheet2", LOADTESTDATAPROVIDER);
}
The data is being returned correctly from the excel but it seems like it is getting overwritten when placed into the object class. The data object class is being initialized from both test classes something like this
#Test(dataProvider = "tradeData")
public void connectAndPushMessage(String sellerName,
String buyerName,
String SIN){
testMessage tMessage = new testMessage();
tMessage.setSellerName(sellerName);
tMessage.setBuyerName(buyerName);
tMessage.setSIN(SIN);
}
Below is the testng.xml that I have used.
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Parallel Testing" parallel="classes" thread-count="2">
<test name="Test run 1">
<classes>
<class name="test.xxx.performance.InjectTrades_TestRun1"/>
<class name="test.xxx.performance.InjectTrades_TestRun2"/>
</classes>
</test>
</suite>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Parallel Testing" parallel="tests" thread-count="2">
<test name="Test run 1">
<classes>
<class name="test.xxx.performance.InjectTrades_TestRun1"/>
</classes>
</test>
<test name="test run 2">
<classes>
<class name="test.xxx.performance.InjectTrades_TestRun2"/>
</classes>
</test>
I am getting the same result from both xmls so rather six distinct messages being created/pushed into the system(based on two excel sheets) the code is pushing three distinct messages repeated twice. I was/am under the impression that testNg should have take care of this as both classes/tests are running as separate threads.
EDIT
Below is the snippet of the Test object class. All attributes are declared private
public class testMessage{
private String currentBusinessDate;
private String sellerName = "";
private String buyerName= "";
private String sin= "";
....
public testMessage() {
cTradeID = "T" + CommonUtils.randomNumber(12);
sRef = CommonUtils.randomNumber(12);
requestId = "1" + CommonUtils.randomNumber(5);
settlementRequestStateCode = "New";
currencyTypeCode = "USD";
}
public String getCurrentBusinessDate() {
return currentBusinessDate;
}
public void setCurrentBusinessDate(String currentBusinessDate) {
this.currentBusinessDate = currentBusinessDate;
}
public String getsellerName () {
return currentBusinessDate;
}
public void setsellerName (String currentBusinessDate) {
this.currentBusinessDate = currentBusinessDate;
}
public String getBuyerName () {
return currentBusinessDate;
}
public void setBuyerName (String currentBusinessDate) {
this.currentBusinessDate = currentBusinessDate;
}
....
Used TestNG version is not mentioned, also ExcelUtils.getDataFromExcelSheet implementation is not shared, but both these 2 things might be related to such unexpected behavior.
I'm going to share my experiment result in order to confirm, that there is no issue with the TestNG parallelization itself, at least for TestNG 7.5.
Test Class 1
class T1 {
#Test(dataProvider = "tradeData")
public void connectAndPushMessage(String arg) {
System.out.println(arg);
}
#DataProvider(name = "tradeData")
public Object[][] createMessage() {
return new Object[]{
{ "T1.createMessage-data-1" },
{ "T1.createMessage-data-2" },
{ "T1.createMessage-data-3" },
};
}
}
Test Class 2
class T2 {
#Test(dataProvider = "tradeData")
public void connectAndPushMessage(String arg) {
System.out.println(arg);
}
#DataProvider(name = "tradeData")
public Object[][] createMessage() {
return new Object[]{
{ "T2.createMessage-data-1" },
{ "T2.createMessage-data-2" },
{ "T2.createMessage-data-3" },
};
}
}
testng.xml
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Parallel Testing" parallel="tests" thread-count="2">
<test name="Test run 1">
<classes>
<class name="samples.T1"/>
</classes>
</test>
<test name="test run 2">
<classes>
<class name="samples.T2"/>
</classes>
</test>
</suite>
Output:
T1.createMessage-data-1
T2.createMessage-data-1
T2.createMessage-data-2
T1.createMessage-data-2
T2.createMessage-data-3
T1.createMessage-data-3
The same for
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Parallel Testing" parallel="classes" thread-count="2">
<test name="Test run 1">
<classes>
<class name="samples.T1"/>
<class name="samples.T2"/>
</classes>
</test>
</suite>
Try to recheck this with TestNG 7.5, and look at your ExcelUtils.getDataFromExcelSheet method implementation, it should be thread-safe.

#AfterTest TestNG annotation is not called

I'm doing some tests using Java + TestNG, but I noticed that the tests are not executing the #AfterTest method. The browser remains open when the other tests are running (when it runs the first test, CreateNewUserWithValidData(), this one doesn't call the #AfterTest method, causing that the other tests fail). I need that every test call the #AfterTest method.
My testng.xml file has the following structure:
<suite name="Sample Tests" verbose="1" >
<listeners>
<listener class-name="Utilities.Listeners.TestListener"></listener>
<listener class-name="Utilities.Listeners.AnnotationTransformer"></listener>
</listeners>
<test name="Regression" >
<classes>
<class name="Tests.AutomationPracticesTests">
<methods>
<include name="CreateNewUserWithValidData" />
<include name="LoginWithAValidUser" />
<include name="LoginWithAnInvalidUser" />
</methods>
</class>
</classes>
</test>
</suite>
My BaseTest class looks like this.-
public class BaseTest {
protected String baseURL;
protected WebDriver driver;
protected WebDriverWait wait;
protected APAuthenticationPage apAuthenticationPage;
protected APCreateAccountPage apCreateAccountPage;
protected APHomePage apHomePage;
protected APMyAccountPage apMyAccountPage;
protected APShoppingCartAddressesPage apShoppingCartAddressesPage;
protected APShoppingCartOrderConfirmationPage apShoppingCartOrderConfirmationPage;
protected APShoppingCartOrderSummaryBankwirePage apShoppingCartOrderSummaryBankwirePage;
protected APShoppingCartPaymentMethodPage apShoppingCartPaymentMethodPage;
protected APShoppingCartShippingPage apShoppingCartShippingPage;
protected APShoppingCartSummaryPage apShoppingCartSummaryPage;
public WebDriver getDriver() {
return driver;
}
#BeforeTest(alwaysRun = true)
public void setUp() {
Log.info("I am in Before Method! Test is starting!");
driver = WebDriverFactory.getDriver(BrowserType.Chrome);
wait = new WebDriverWait(driver, 10);
driver.manage().window().maximize();
}
#BeforeMethod
public void initSetup() {
String propertiesFile = "data.properties";
PropertyReader propertyReader = new PropertyReader();
apAuthenticationPage = new APAuthenticationPage(driver);
apCreateAccountPage = new APCreateAccountPage(driver);
apHomePage = new APHomePage(driver);
apMyAccountPage = new APMyAccountPage(driver);
apShoppingCartAddressesPage = new APShoppingCartAddressesPage(driver);
apShoppingCartOrderConfirmationPage = new APShoppingCartOrderConfirmationPage(driver);
apShoppingCartOrderSummaryBankwirePage = new APShoppingCartOrderSummaryBankwirePage(driver);
apShoppingCartPaymentMethodPage = new APShoppingCartPaymentMethodPage(driver);
apShoppingCartShippingPage = new APShoppingCartShippingPage(driver);
apShoppingCartSummaryPage = new APShoppingCartSummaryPage(driver);
baseURL = propertyReader.getProperty(propertiesFile, "AUTOMATION_PRACTICE_URL");
}
#AfterTest(alwaysRun = true)
public void tearDown() {
Log.info("I am in After Method! Test is ending!");
driver.close();
driver.quit();
}
}
And my tests are the following ones.-
public class AutomationPracticesTests extends BaseTest {
// Properties
private String emailAddress, password;
// Tests
#Test(description = "It creates a new user in the store",
priority = 1)
public void CreateNewUserWithValidData(Method method) {
startTest(method.getName(), "It creates a new user in the store");
emailAddress = Mocks.personalData().get(0).getEmail();
password = Mocks.personalData().get(0).getPassword();
apHomePage.goTo(baseURL);
apHomePage.clickOnSignInButton();
apAuthenticationPage.fillCreateAccountForm(emailAddress);
apAuthenticationPage.clickOnCreateAccountButton();
apCreateAccountPage.fillRegisterForm(Mocks.personalData());
apCreateAccountPage.clickOnRegisterButton();
Assert.assertTrue(apMyAccountPage.isLoaded());
}
#Test(description = "It logins successfully in the store with a valid user",
priority = 2)
public void LoginWithAValidUser(Method method) {
apHomePage.goTo(baseURL);
apHomePage.clickOnSignInButton();
apAuthenticationPage.fillSignInForm(emailAddress, password);
apAuthenticationPage.clickOnSignInButton();
Assert.assertTrue(apMyAccountPage.isLoaded());
}
#Test(description = "It throws an error when the user attempts to login with an invalid user",
priority = 3)
public void LoginWithAnInvalidUser(Method method) {
apHomePage.goTo(baseURL);
apHomePage.clickOnSignInButton();
apAuthenticationPage.fillSignInForm(Mocks.invalidPersonalData().getEmail(), Mocks.invalidPersonalData().getPassword());
apAuthenticationPage.clickOnSignInButton();
Assert.assertEquals("Authentication failed.", apAuthenticationPage.IsErrorBannerDisplayed());
}
}
I'm suspecting that's something related to the testng.xml file (but, tbh, there are some things that I don't understand about how to configure correctly this file).
I'll appreciate any help to solve my problem. Thanks in advance!
It's not a bug. It work as expected.
BeforeTest
BeforeMethod
Method 1: CreateNewUserWithValidData
BeforeMethod
Method 2: LoginWithAValidUser
BeforeMethod
Method 3: LoginWithAnInvalidUser
AfterTest
If you want to close the browser before method 2, then you need to change AfterTest --> AfterMethod, and initialize browser in BeforeMethod
If you just want to change the testng.xml
<test name="test1">
<classes>
<class name="Tests.AutomationPracticesTests">
<methods>
<include name="CreateNewUserWithValidData"/>
</methods>
</class>
</classes>
</test>
<test name="test2">
<classes>
<class name="Tests.AutomationPracticesTests">
<methods>
<include name="LoginWithAValidUser"/>
</methods>
</class>
</classes>
</test>
<test name="test3">
<classes>
<class name="Tests.AutomationPracticesTests">
<methods>
<include name="LoginWithAnInvalidUser"/>
</methods>
</class>
</classes>
</test>

When Running Selenium with TestnG I get FAILED CONFIGURATION: BeforeClass setUp?

#BeforeClass I get null null errors I believe it's something with my before class.What about optional do you need them? FAILED CONFIGURATION: #BeforeClass setUp(null, null) I tried to add different maven dependiencies maybe its because of selenium version its still wont work.
public class Practice {
WebDriver driver;
//Check this ont out
#BeforeClass(alwaysRun = true)
#Parameters({ "browser", "url" })
public void setUp(#Optional("browser") String browser, #Optional("url") String url) {
BaseTest base = new BaseTest(browser, url);
driver = base.getDriver();
}
#Test
public void Check() {
try {
System.out.println("Passed Test case...");
Assert.assertTrue(driver.getTitle().contentEquals("Google"));
} catch (Exception ee) {
System.out.println("NOOOOO ");
ee.printStackTrace();
Assert.assertEquals("noooo " + ee, "iT SHOULD NOT fAIL");
}
}
public class Selen {
private WebDriver driver;
private String browser;
private String url;
public Selen(String browser, String url) {
this.browser = browser;
this.url = url;
if (browser.equalsIgnoreCase("firefox")) {
System.setProperty("webdriver.firefox.marionette",
"C:\\Users\\geckodriver.exe");
final FirefoxProfile firefox = new FirefoxProfile();
driver = new FirefoxDriver();
driver.get(url);
}
else if (browser.equalsIgnoreCase("chrome")) {
// set path to chromedriver.exe
System.setProperty("webdriver.chrome.driver", "C:\\Drivers\\chromedriver.exe");
ChromeOptions options = new ChromeOptions();
options.addArguments("--enable-automation", "test-type=browser", "--disable-plugins", "--disable-infobars",
"--disable-notifications", "start-maximized");
driver = new ChromeDriver(options);
driver.get(url);
}
else if (browser.equalsIgnoreCase("Edge")) {
// set path to Edge.exe
System.setProperty("webdriver.edge.driver", ".\\MicrosoftWebDriver.exe");
driver = new EdgeDriver();
driver.get(url);
} else {
}
}
public String getBrowser() {
return this.browser;
}
public String getBaseUrl() {
return this.url;
}
public WebDriver getDriver() {
return this.driver;
}
#AfterClass
public void tearDown(WebDriver driver) {
quitDriver(driver);
}
protected static void quitDriver(WebDriver driver) {
try {
if (driver != null) {
driver.quit();
}
} catch (Exception ee) {
System.out.println("Failed: " + ee);
;
}
}
**Failed Configuration**
[RemoteTestNG] detected TestNG version 6.14.3
Check() test case...
There was a problem:
java.lang.NullPointerException
at com.seleniumae.exercise.Practice.Check(Practice.java:44)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:583)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:719)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:989)
TeNg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
<test thread-count="5" name="Test">
<parameter name="browser" value= "Chrome" />
<parameter name="url" value="https://www.google.com/"/>
<classes>
<class name="com.seleniumae.exercise.Practice"/>
<class name="com.seleniumae.exercise.Practice1"/>
<class name="com.seleniumae.exercise.Practice2.java"/>
</classes>
</test> <!-- Test -->
<test thread-count="5" name="Test">
<parameter name="browser" value ="Firefox" />
<parameter name="url" value="https://www.google.com/"/>
<classes>
<class name="com.seleniumae.exercise.Practice"/>
<class name="com.seleniumae.exercise.Practice1"/>
<class name="com.seleniumae.exercise.Practice2"/>
</classes>
</test> <!-- Test -->
<test thread-count="5" name="Test">
<parameter name="browser" value="InternetExplore" />
<parameter name="url" value="https://www.google.com/"/>
<classes>
<class name="com.seleniumae.exercise.Practice"/>
<class name="com.seleniumae.exercise.Practice1"/>
<class name="com.seleniumae.exercise.Practice2.java"/>
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
The issue could be about parameters with browser taking one parameter like chrome when it should be another parameter.
Syntax to define #Optional annotation :
public void setUp(#Optional("browser_name") String browser, #Optional("site_name") String url)
And you are implementing in following way without using #Optional("value")
public void setUp(#Optional String browser, #Optional String url) throws MalformedURLException {
TestNG.xml - please write parameters like below
<suite name="Suite">
<test thread-count="5" name="Test">
<parameter name="url" value="https://www.google.com/"/>
<parameter name="browser" value= "Chrome" />
Note - TestNG provides you flexibility of declaring parameters as optional. When we declare a parameter as optional and If defined parameter is not found in your testng.xml file, The test method will receive the default value which is specified inside the #Optional annotation.

Second class of testing.xml doesn't execute

I have created 2 separate classes to test a webpage. But, unfortunately when I add them both to the testing.xml, only one of them execute and the other doesn't. The browsers open in parallel even after setting them to preserve-order="true" parallel="false" in the XML. I'm confused as to where I'm doing it wrong.
This is my XML file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite" preserve-order="true" parallel="false">
<test name="Test">
<classes>
<class name="TestServiceNow.loginOne"/>
<class name="TestServiceNow.loginTwo"/>
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
loginOne is as follows:
package TestServiceNow;
import org.testng.annotations.Test;
import ServiceNow.login;
public class loginOne extends loginTest{
#Test
public void test_Login(){
//Create Login Page object
objLogin = new login(driver);
//login to application
objLogin.loginGurukula("admin", "admin");
}
}
loginTwo is as follows:
import org.testng.annotations.Test;
import ServiceNow.login;
public class loginTwo extends loginTest{
#Test
public void test_Login_Fail(){
//Create Login Page object
objLogin = new login(driver);
//login to application
objLogin.loginGurukula("admin", "admin1");
}
}
The base class is as follows:
public class loginTest {
DesiredCapabilities capabilities = DesiredCapabilities.chrome();
File file = new File("C:/Users/gattu_000/Documents/selenium-java-3.0.0-beta2/chromedriver_win32/chromedriver.exe");
WebDriver driver;
login objLogin;
#BeforeClass
public void a() {
driver = new ChromeDriver(capabilities);
capabilities.setCapability("marionette", true);
System.setProperty("webdriver.chrome.driver", file.getAbsolutePath());
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
System.out.println("Before class called");
}
#BeforeTest
public void setup(){
System.out.println("Before test called");
driver.get("http://localhost:8080/#/login");
}
#AfterTest
public void close() {
System.out.println("After test called");
}
#AfterClass
public void b() {
System.out.println("After class called");
driver.close();
}
}
The results look like
After the Edit
You are extending loginTest by both loginOne and loginTwo. But in loginTest you initialized your driver. That's why two browser are opening. To get around this issue, you can initialize your driver inside a setup method like #BeforeTest or #BeforeSuite. As an example here's a code snippet -
#BeforeSuite
public void a() {
driver = new ChromeDriver(capabilities);
System.out.println("Before suite called");
}
Do other things as usual like before except the initialization part.
Edit
I missed something. You are closing your driver at the after test method. To run your tests properly remove the driver.close() from your after test method and place it to aftereSuite section.
The XML is supposed to be like this:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite" preserve-order="true">
<test name="Test">
<classes>
<class name="TestServiceNow.loginOne"/>
</classes>
</test> <!-- Test -->
<test name="Test1">
<classes>
<class name="TestServiceNow.loginTwo"/>
</classes>
</test>
</suite> <!-- Suite -->
To launch the browser twice, we need to have 2 separate tests. (Possibly, this may be one of the solutions out of many)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Selenium Test Suite">
<test name="Selenium Test Suite">
<classes>
<class name="packagename.classname1"/>
<class name="packagename.classname1"/>
</classes>
</test>
</suite>
Which is proper. If you are getting null point don't use driver in all the class. because of that only you are getting null pointer i guess.

TestNG: How i can put parameters for java method on command line?

I have test script like:
public class AppTest {
#Test
public void print(String strInput)
{
System.out.println("String: " + strInput);
}
}
and Testng.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Default suite">
<test verbose="2" name="Default test">
<classes>
<class name="Test.printTest.AppTest"/>
</classes>
</test> <!-- Default test -->
</suite> <!-- Default suite -->
How I can put parameter on command line instead of on testng.xm ?
You can make a data provider that will look for attributes in system properties:
public class AppTest {
#DataProvider
public static Object[][] dp() {
String input = System.getProperty("input");
return new Object[][] {
new Object[] { input }
}
}
#Test(dataProvider="dp")
public void print(String strInput) {
System.out.println("String: " + strInput);
}
}
Then, you just have to run it by adding -Dinput="HelloWorld param in your command line.

Categories