Error when calling dependency of one method of another class into other class in TestNG automation - testing

I want to add dependency of one test method from class A to another testMethod in class B.
Whenever I am running method "testTwo()" from class B I am getting error as
"method B.testTwo() depends on nonexistent group A.Group1" , my class structure is as below .
public class A
{
#Test(groups={"A.Group1"})
public void testOne(){}
}
public class B
{
#Test(dependsOnGroups={"A.Group1"})
public void testTwo(){}
}
Can anyone please guide here ?,
also My test.xml looks like below
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="TEST-AUTOMATION" thread-count="1"
preserve-order="true" data-provider-thread-count="1">
<test name="TESTS">
<classes>
<class name="A"/>
<class name="B"/>
</classes>
</test>
</suite>

Related

When a #BeforeTest method fails, why is it not being listed in the testng-failed.xml?

I am using maven with testng 6.14.3.
Here is my code structure:
testng.xml
<?xml version="1.0" encoding="UTF-8"?>
<suite name="set-3" parallel="tests" thread-count="10">
<listeners>
<listener class-name="org.uncommons.reportng.HTMLReporter" />
</listeners>
<test name="Customer Tests">
<groups>
<run>
<include name="abc"/>
</run>
</groups>
<classes>
<class name="apps.Test1_BeforeTest_Of_Test2"></class>
<class name="apps.Test2"></class>
</classes>
</test>
</suite>
Test1_BeforeTest_Of_Test2.java
public class Test1_BeforeTest_Of_Test2{
#BeforeTest(groups = {"abc"})
public void test1Method() throws Exception {
}
#AfterTest(groups={"abc"})
public void test1AfterMethod() throws Exception {
}
}
Test2.java
public class Test2{
#Test(groups = {"abc"})
public void test2Method(){
}
}
During my run, Test1_BeforeTest_Of_Test2 class fails. So, Test2 is marked as skipped.
But, when I look at the testng-failed.xml that is generated at the end of the run, the failed #BeforeTest class (Test1_BeforeTest_Of_Test2) is not included/listed:
testng-failed.xml
<?xml version="1.0" encoding="UTF-8"?>
<suite thread-count="10" name="Failed suite [set-3]" parallel="tests">
<listeners>
<listener class-name="org.uncommons.reportng.HTMLReporter"/>
</listeners>
<test name="Customer Tests(failed)">
<groups>
<run>
<include name="abc"/>
</run>
</groups>
<classes>
<class name="apps.Test2">
<methods>
<include name="test2Method"/>
</methods>
</class>
</classes>
</test>
</suite>
Is this expected behaviour? Or a bug/gap in testng-failed.xml?
Ideally, when we re-run the failed tests, we expect the #BeforeTest to run as well, because it is pre-req for Test 2.
TestNG currently seems to be honouring configurations to be considered in the testng-failed.xml if its part of the skipped test method's test class i.e., the configuration (which is perhaps what has caused a test to be skipped) needs to reside in the same java class as your skipped method for TestNG to consider it to be included.
In your example, that's not the case and the configuration method exists in a different test class (which is perfectly valid).
This looks like a bug in TestNG to me.
I have submitted a bug on your behalf on the TestNG project and will get it fixed in the upcoming version (7.5.0).
Defect : https://github.com/cbeust/testng/issues/2611

extent report with one master test class

i have created 2 different test classes (test1.java and test2.java), having multiple tests in each class. to simplify, i have created one master test class, in which i have created 2 tests and called the methods from test1page.java and test2page.java. now when i create the extent reports it only gives 2 results. i want all the test result which i have created in test1.java and test2.java.
below is my MasterTest.java
public class MasterTest extends TestBase {
#BeforeClass()
//before class method
#Test(priority=1)
// methods from the test1page.java class
#Test(priority=2)
// methods from the test2page.java class
#AfterClass
}
below is my xml file to run
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="smoke">
<listeners>
<listener class-name="report.TestListener" />
</listeners>
<test name="master">
<classes>
<class name="tests.MasterTest">
</class>
</classes>
</test>
</suite>

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 can I print in log the number of tests running as part of one group in TestNG?

I need to print this before actual execution of tests start. Anyways, we get the count at last of execution.
Say for example if my testng.xml looks like:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Suite1">
<test name="test1">
<groups>
<run>
<include name="functest" />
</run>
</groups>
<classes>
<class name="GroupTestExample" />
</classes>
</test>
</suite>
And there are 10 methods in class GroupTestExample which comes under group functest, it should print 10 in log as soon as it starts running.
Create a custom Listener which extends the org.testng.TestListenerAdapter. After that override the following method:
public class MyCustomListener extends TestListenerAdapter {
#Override
public void onStart(ITestContext testContext) {
super.onStart(testContext);
System.out.println("Number of Test Methods: " + testContext.getAllTestMethods().length);
}
}
You can add your custom listener by using #Listeners annotation on your main class of your test, like
#Listeners({MyCustomListener.class})
public class MyMainTestClass { ... }
You can find more information in TestNG doc:
TestNG Listeners -
http://testng.org/doc/documentation-main.html#testng-listeners

Sharing single instance of class across multiple tests

I am using Page object pattern with selenium webdriver and testng.
I want to access instance of one page object class in another class across multiple <test>.
for e.g.
<test name="Login scenario">
<classes>
<class name="sanitytests.LoginTests">
<methods>
<include name="validLogin"/>
</methods>
</class>
</classes>
</test>
<test name="scenario2" preserve-order="true" parallel="false">
<classes>
<class name="sanitytests.HomePageTests">
<methods>
<include name="clickOnMyAccountFromHome"/>
</methods>
</class>
</classes>
</test>
in my LoginTests class I am using instance of homePage class
#Test()
public void validLogin(ITestContext context) throws Exception {
loginPage.loginDetails(username,password);
homePage = loginPage.loginAsValidUser();
context.setAttribute("homePage",homePage);
}
my HomePageTests class
#Test()
public void clickOnMyAccountFromHome(ITestContext context) throws Exception {
homePage = (HomePage) context.getAttribute("homePage");
myAccountPage = homePage.navigateToMyAccountPage();
context.setAttribute("myAccountPage", myAccountPage);
}
i am getting null pointer exception because ItestContext is used to share parameter between methods not between tests. Is there any alternative?
From what i have read about "ITestContext", it is related to TestNG classes/objects/methods. You can create the HomePage as a static and it will be available for entire suite run.
The page object pattern does not state that objects can only be created once. Create new instances in each test.