TestNG #BeforeGroup is not executed before the group is run - java

Given the following codes:
public class NewTest {
private Object _foreground = null;
#BeforeGroups("regression")
public void setUp() {
System.out.println("executed? setUp");
_foreground = new MyObject();
}
#Test(groups="regression")
public void testMyObjectToString() throws Exception {
System.out.println("??? ");
System.out.println(_foreground == null);
String value = _foreground.toString();
Assert.assertTrue(value != null);
}
}
And the testNG.xml:
<groups>
<run>
<include name="regression" />
</run>
</groups>
<classes>
<class name="com.automation.test.NewTest"/>
</classes>
When I tried to run this, the print statements say:
???
true
So that means _foreground is null, meaning the setUp method is not executed.
TestNG also shows java.lang.NullPointerException on the line:
String value = _foreground.toString();
However I have no idea what I missed. Looks to me the "regression" group will be run and the setUp method with #beforeGroup will be run before testMyObjectToString with #Test. Apparently this is not what is happening..

It is a very stupid mistake that maybe someone new to testNG may make...
#BeforeGroups("regression")
This is a wrong usage.. The correct usage should be:
#BeforeGroups(groups = "regression")
Took me two days!!

Related

TestNG: Test Method In Second Class of Test Suite Being Called Only Once

I have two test methods in different classes. The first method, let's say "createCustomer" is using dataProvider to get the inputs from an excel file and creates three customers.
#Test(dataProvider = "createCustomerTestData", dataProviderClass = createCustomerDataProvider.class)
public void addStockAccountWithAllInput(ITestContext context) throws JsonProcessingException {
//Rest-Assured code goes here
ISuite suite = context.getSuite();
suite.setAttribute("customerID", js.get("customerID"));
}
The second method, let's say "getCustomer" is supposed to get the id of the customers from output of "createCustomer" method and use them as input, using ITestContext and ISuite.
#Test
public void testGetCustomer(ITestContext context) {
ISuite suite = context.getSuite();
//Rest-Assured code goes here
Assert.assertEquals(js.getString("customerID"), suite.getAttribute("customerID"));
}
When I run the test suite from the testng xml file, only the id of the third created customer will be passed to "getCustomer" method.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="All Test Suite">
<test verbose="2" preserve-order="true"
<classes>
<class name="addCustomer">
<methods>
<include name="testAddCustomer"/>
</methods>
</class>
</classes>
</test>
<test verbose="2" preserve-order="true"
<classes>
<class name="getCustomer">
<methods>
<include name="testGetCustomer"/>
</methods>
</class>
</classes>
</test>
</suite>
How can I change the settings or the code so that the "getCustomer" method gets called every time createCustomer is called and a customer created?
This would work for you.
//Create a temp list of String to save ID
static List<String> ids = new ArrayList<>();
#Test(dataProvider = "createCustomerTestData", dataProviderClass = createCustomerDataProvider.class)
public void addStockAccountWithAllInput(ITestContext context) throws JsonProcessingException {
//Rest-Assured code goes here
ISuite suite = context.getSuite();
String id = js.get("customerID");
ids.add(id);
suite.setAttribute("customerIDs", ids);
}
#Test
public void testGetCustomer(ITestContext context) {
ISuite suite = context.getSuite();
//Make api call based on the list IDs from above test
for (int i = 0; i < suite.getAttribute("customerIDs").size(); i++){
//Rest-Assured code goes here
Assert.assertEquals(js.getString("customerID"), suite.getAttribute("customerIDs").get(i));
}
}

TestNG Dataprovider closing driver after each iteration

I am trying to run a dataprovider based test using ANT. My main class points to testNG file
XmlSuite suite=new XmlSuite();
suite.setName("Test Results");
suite.setPreserveOrder(true);
List<XmlSuite> suits=new ArrayList<XmlSuite>();
suits.add(suite);
List<XmlPackage> xpackage=new ArrayList<XmlPackage>();
xpackage.add(new XmlPackage(TestProperties.TESTNG_PACKAGE.toString()));
XmlTest test=new XmlTest(suite);
test.setPackages(xpackage);
String groups=TestProperties.TESTNG_GROUP.toString();
System.out.println("groups are:"+groups);
String groupArray[]=groups.split(",");
List<String> includedGroups=new ArrayList<String>();
includedGroups.addAll(Arrays.asList(groupArray));
test.setIncludedGroups(includedGroups);
TestNG tng=new TestNG();
tng.setOutputDirectory("test-output");
tng.setXmlSuites(suits);
tng.run();
System.exit(0);
Now, in my Testcase file, I have
#BeforeClass(alwaysRun = true)
public void pretest() throws IOException, GeneralSecurityException {
Pretest
}
#Test(groups= {"indicatorGroup","",""},description = "Validate indicator uploaded", dataProvider = "getIndicatorData")
public void indicatorUpload(String txt){
test
}
#DataProvider
public Object[] getIndicatorData() throws IOException, GeneralSecurityException
{
bla bla
for(int i=0; i<contents.length; i++) {
System.out.println(contents[i]);
if(!contents[i].contains("README")) {
blah blah
System.out.println(path);
names.add(path);
}
}
String[] myArray = new String[names.size()];
names.toArray(myArray);
return myArray;
}
#AfterClass(alwaysRun = true)
public void afterMethod() throws IOException {
System.out.println("Deleting all files after operation.....");
}
The problem is, they run without any issues, if i run from Testng. ie if i right click on the file, click on run, click on Run as Testng Test.
But if I run from my build file, after the first iteration, the driver I bring up in before class, closes and the rest of the tests fail. This causes my tests to fail in jenkins.
Can someone please help me out?
After many trials, I found out that the testng xml created By my trigger file had
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="IndicatorSuite" data-provider-thread-count="1">
<test name="Test Basics 1">
<groups>
<run>
<include name="indicatorUpload" />
</run>
</groups>
<classes>
<class name="Uploads.IndicatorFileUpload">
<class name="Uploads.IndicatorFileUpload1">
<class name="Uploads.IndicatorFileUpload2">
</methods>
</class>
</classes>
</test>
</suite>
Even though my test group was correct, I had given test package, because of which all my testcase files had been added as classes. All of these had a listener which would close the driver after testrun. I dont know much about testng, but I think it mixed up the listeners. In my Trigger file, when I added just
TestNG tng=new TestNG();
tng.setOutputDirectory("test-output");
//tng.setXmlSuites(suits);
tng.setTestClasses(new Class[] { IndicatorFileUpload.class });
tng.run();
it worked!

Java Selenium Testng - Factory not working on Windows

I set up a project using Intellij on Linux using Selenium and Testng using the factory method with dataProviders. On Linux the process runs as the following:
**Data 1:**
initialize
second
AfterTest
**Data 2**
initialize
second
AfterTest
But when I transferred the project onto a Windows machine, installed all of the libraries (still using intellij) I get the following output:
Initialize
Initialize(1)
second
second (1)
AfterTest
I'm not too sure why I'm getting differences since it's the same code. Please see the code below:
#DataProvider(name = "data")
public static Object[][] data() {
// This is where I get the data from
}
#Factory(dataProvider = "data")
public TestSuite1(Data data)
{
super();
this.data = data;
}
#Test(priority = 1, description = "First test")
public void initialize()
{
System.out.println("DO THIS FIRST");
}
#Test(priority = 2, description = "Do this after")
public void second()
{
System.out.println("DO THIS AFTER");
}
#AfterClass
public void AfterTest() throws InterruptedException
{
System.out.println("I HAVE FINISHED THE TEST");
}
I see here :https://howtodoinjava.com/testng/testng-factory-annotation-tutorial/ That "#Factory" must be used with "#DataProvider" to test ...
I didn't see "#DataProvider" in your code ... and it seem to not use a correct form of code for TestNG...
That could be why there is a difference ...
You have to check your testNg xml file as well. since I cannot see your any test steps use data from data provider. Your second script is similar to parallel test execution. please make sure your suite details like below.
<suite name="Suite" parallel="false" thread-count="0" verbose="2">
<test name="TestName"> <!--Do not add any other unless its necessary-->
<classes>
<class name="className"/>
</classes>
</test>

Unable to skip passed test cases and test only failed test case in testNG

I'm trying to automate a website testing using testNG.
Let assume I have created 3 test cases one for each webpage(although there are more than 50 test cases in my case but just for simplifying the issue I have considered 3 only).
Now, my starting 2 test cases are passing but my 3rd test case is getting failed. I am making the code change to that 3rd page and I want just to run that 3rd test case but when I am running my code, everytime new IE driver instance is getting created and testing starts from beginning.
How to use existing driver instance and test the 3rd webpage only. I tried googling this out but couldn't find anything useful.
Any help would be appreciated.
If you want to ignore particular test, you can use this snippet:
import org.testng.Assert;
import org.testng.annotations.Test;
public class IgnoreTest {
#Test(enabled = false) // this test will be ignored
public void testPrintMessage() {
System.out.println("This test is ignored");
}
#Test
public void testSalutationMessage() { // this will be executed
System.out.println("Test works");
}
}
When you execute this class, it will be only second test executed. I don't know if you have stored all 50 tests in one class(hopefully not), but if yes, there is a possibility to group your tests. To be able to do this you can use this sample:
import org.testng.Assert;
import org.testng.annotations.Test;
public class GroupTestExample {
#Test(groups = { "functest", "checkintest" })
public void testPrintMessage() {
System.out.println("Inside testPrintMessage()");
}
#Test(groups = { "checkintest" })
public void testSalutationMessage() {
System.out.println("Inside testSalutationMessage()");
}
#Test(groups = { "functest" })
public void testingExitMessage() {
System.out.println("Inside testExitMessage()");
}
}
then xml file would be 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">
<groups>
<run>
<include name = "functest" />
</run>
</groups>
<classes>
<class name = "GroupTestExample" />
</classes>
</test>
</suite>
then after compiling your test classes, use this command:
C:\TestNG_WORKSPACE>java -cp "C:\TestNG_WORKSPACE" org.testng.TestNG testng.xml
More explained information you will get in this tutorials:
ignore tests
group tests

TestNG: #BeforeGroups gets called for every group entry even though I am running one group of tests

I see a problem in my testNG tests, the test is as follows.
public class testNG {
#BeforeGroups(groups = {"smoketests", "functionaltests"})
public void before() {
System.out.println("Before Groups");
}
#Test(groups = {"smoketests", "functionaltests"})
public void test() {
System.out.println("Test");
}
#AfterGroups(groups = {"smoketests", "functionaltests"})
public void after() {
System.out.println("After Groups");
}
}
When I run the tests from testNG command line by
java -cp :libs/* org.testng.TestNG -testjar libs/testNGLib.jar -groups smoketests
(Assume that the test jar is in some libs folder)
The output I get is as follows
Before Groups
Before Groups
Test
After Groups
I am not sure why the BeforeGroups is called twice even though I am only interested in running the test that's part of the smoketests group.
The problem doesn't happen if I only have smoketests group in the #Test directive, but I still don't understand the issue with #BeforeGroups with multiple groups in place.
Try use
#BeforeSuite(alwaysRun = true) instead of #BeforeGroups(groups = {"smoketests", "functionaltests"})
#AfterSuite(alwaysRun = true) instead of #AfterGroups(groups = {"smoketests", "functionaltests"})
Getting the same issue while running the test suite.
<suite name="Test Suite">
<test name="GroupTest">
<groups>
<run>
<include name="sanity"/>
</run>
</groups>
<classes>
<class name="SampleTest"/>
</classes>
</test>
</suite>
Below is the test class:
public class SampleTest {
#BeforeGroups(groups = {"sanity","regression"})
void beforeGroup(){
System.out.println("Before Group");
}
#AfterGroups(groups = {"sanity","regression"})
void afterGroups(){
System.out.println("After Groups");
}
#Test(groups = {"sanity"})
void m1(){
System.out.println("m1");
}
#Test(groups = {"sanity","regression"})
void m3(){
System.out.println("m3");
}
#Test(groups = {"sanity"})
void m4(){
System.out.println("m4");
}
#Test(groups = {"regression"})
void m5(){
System.out.println("m5");
}
#Test
void m6(){
System.out.println(Sample.class.getName());
}
}
So when I am runnting the testng.xml, getting the following result:
Before Group
m1
Before Group
m3
After Groups
m4
After Groups
The following is the result after changing the group name to regression.
Before Group
m3
After Groups
m5
After Groups
#BefroreGroups and #Aftergroups get executed for both the group entries. Using TestNG 6.11 version.

Categories

Resources