testng "groups" testing fails - java

i have a class Calc which implements two methods add(int a, int b) and div(int a, int b) and a test class of this class:
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
public class CalcTest {
Calc c;
#BeforeClass
public void init() {
c = new Calc();
}
#Test(groups = "t1")
public void addTest() {
System.out.println("Testing add() method");
Assert.assertEquals(c.add(10, 5), 15);
}
#Test
public void divTest() {
System.out.println("Testing div() method");
Assert.assertEquals(c.div(10, 5), 2, 0);
}
#AfterClass
public void free() {
c = null;
}
}
and i have a testing.xml file to suite tests:
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="first tests">
<test name="first test">
<groups>
<run>
<include name="t1" />
</run>
</groups>
<classes>
<class name="CalcTest" />
</classes>
</test>
</suite>
I just had a first look at the groups in testng so i would like to try it, butif i run testing.xml file i'm getting nullPointerException at line:
Assert.assertEquals(c.add(10, 5), 15);
-if i remove the "groups" annotation from the test method it works fine, thanks

You need to keep your #BeforeClass annotation in the group. Add (groups = "t1") to your beforeclass annotation.

pretty solution, as there might be more groups in the future, would be:
#BeforeClass(alwaysRun = true)
public void init() {
c = new Calc();
}
This causes your BeforeClass to run always, no matter what group you are running.

Related

How to avoid executing the method written in #AfterSuite if a single test is executed as 'TestNG Test' or using the 'Run' command provided by plugin

BaseTest Class
public class BaseTest extends Base {
LoginPage login;
Logger logger = Logger.getLogger(Base.class);
#BeforeMethod()
public void setUp() throws IOException, IOException {
logger.info("starting initialisation method from base class");
initialisation();
logger.info("completed initialisation method from base class");
login = new LoginPage();
logger.info("initialising login page and profile page object");
}
#AfterMethod
public void tearDown() {
logger.info("starting tear down method");
Base.getDriver().close();
logger.info("ending tear down method");
}
#AfterSuite
public void sendEmailWithExtentReport() throws IOException {
logger.info("starting sendEmailWithExtentReport");
Utilities.sendJavaMailAfterExecution();
logger.info("ending sendEmailWithExtentReport");
}
LoginTest class
public class LoginTest extends BaseTest {
#Test(priority = 0,description = "Test case to verify login button is present or not")
public void loginPageLoadingTest() throws IOException, InterruptedException {
logger.info("starting loginPageLoadingTest");
Thread.sleep(2000);
Assert.assertEquals(login.verifyLoginButton(), true);
logger.info("ending loginPageLoadingTest");
}
#Test(priority = 1, description = "Test case to verify login page title")
public void loginPageTitleTest() throws IOException, InterruptedException {
logger.info("starting loginPageTitleTest");
Thread.sleep(2000);
Assert.assertEquals(login.getLoginPageTitle(), "Console");
logger.info("ending loginPageTitleTest");
}
}
testng-console.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Suite">
<listeners>
<listener class-name="com.analyzer.MyTransformer" />
<listener class-name="com.utilities.TestListener"></listener>
</listeners>
<test thread-count="5" name="Test">
<classes>
<class name="com.ui.tests.BaseTest" />
<class name="com.ui.tests.LoginTest" />
<class name="com.ui.tests.FilterTest" /> -->
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
I need to skip the method in #AfterSuite if i am only executing the single test case from multiple test cases in LoginTest class without using testng.xml file, so that I can verify each test case separately. Right now when individual test is executed the method in #AfterSuite is also getting executed. I want to execute the method in #AfterSuite only when test cases are executed using testng.xml file. How can i add a condition in #AfterSuite to achieve this. Also i am using this command '''mvn clean test -Dbrowsername=chrome''' from command prompt. My testng file name is testng-console.xml .The method in #AfterSuite should only get executed when using the tesng-console.xml. Please help.
You can test your suite name for equality to Default Suite. Say you have testng.xml like:
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd" >
<suite name="Suite1" verbose="1" >
<test name="MyTest" >
<classes>
<class name="click.webelement.Suites" />
</classes>
</test>
</suite>
where you define suite name explicitly. Then you can have the logic like this:
package click.webelement;
import org.testng.ITestContext;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.Test;
public class Suites {
#Test
public void doTest(){
System.out.println("Doing test..");
}
#AfterSuite
public void doingAfterSuite(ITestContext testContext){
if(!testContext.getSuite().getName().equalsIgnoreCase("Default Suite")){
System.out.println("Doing after suite");
}
}
}
Since when you run a single test, Default Suite is created you can just test if default suite is set in test context.
UPDATE: Eclipse plugin sets default suite name as Default suite so that I changed equals to EqualsIgnoreCase to cover both Idea and Eclipse

How to configure TestNG to run just a single test case in IntelliJ?

I have two separate packages in my project, one for integration tests and one for unit tests, my testng.xml looks as follows:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd" >
<suite name="All test cases" verbose="1" parallel="classes">
<test name="Integration Tests">
<classes>
<class name="com.sample.integration.ClassC"/>
<class name="com.sample.integration.ClassD"/>
</classes>
</test>
<test name="Unit tests">
<classes>
<class name="com.sample.unit.ClassA"/>
<class name="com.sample.unit.ClassB"/>
</classes>
</test>
</suite>
Class C:
public class ClassC {
#BeforeTest
public void beforeIntegrationTests() {
System.out.println("Before Integration tests");
}
#Test
public void classCMethod() {
System.out.println("Executing class C method");
}
}
Class D:
public class ClassD {
#Test
public void classDMethod() {
System.out.println("Executing class D method");
}
}
Class A:
public class ClassA {
#BeforeTest
public void beforeUnitTests() {
System.out.println("Before unit tests");
}
#Test
public void classAMethod() {
System.out.println("Executing class A method");
}
}
Class B:
public class ClassB {
#Test
public void classBMethod() {
System.out.println("Executing class B method");
}
}
If I run the entire test suite it works as expected as follows:
Before Integration tests
Executing class C method
Executing class D method
Before unit tests
Executing class A method
Executing class B method
However, if I try to either run/debug just classAMethod() from ClassA, it runs beforeUnitTests() [expected] and classAMethod() [expected], however it also runs beforeIntegrationTests() which is not expected. As per the official documentation: #BeforeTest: The annotated method will be run before any test method belonging to the classes inside the <test> tag is run.
How do I configure TestNG and/or IntelliJ to run this correctly?
Side Note: Although I can see that the beforeIntegrationTests() is getting run either by adding a breakpoint in the debug mode or by adding a Thread.sleep in the run mode, the output from this method does not get printed in final console output.
Firstly, is the expectation valid, as in I expect only beforeUnitTests() and classAMethod() to run if I run just the classAMethod().
No, all methods with #BeforeTest annotation will run before execution of method with #Test annotation.
Ideal way to handle this scenario is with groups.
Class A:
public class ClassA {
#BeforeTest(groups="unitTest")
public void beforeUnitTests() {
System.out.println("Before unit tests");
}
#Test(groups="unitTest")
public void classAMethod() {
System.out.println("Executing class A method");
}
}
Class B:
public class ClassB {
#Test(groups="unitTest")
public void classBMethod() {
System.out.println("Executing class B method");
}
}
Class C:
public class ClassC {
#BeforeTest(groups="integrationTest")
public void beforeIntegrationTests() {
System.out.println("Before Integration tests");
}
#Test(groups="integrationTest")
public void classCMethod() {
System.out.println("Executing class C method");
}
}
Class D:
public class ClassD {
#Test(groups="integrationTest")
public void classDMethod() {
System.out.println("Executing class D method");
}
}
testNG XML:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd" >
<suite name="All test cases" verbose="1" parallel="classes">
<groups>
<run>
<include name="unitTest"></include>
</run>
</groups>
<test name="Test Suite">
<classes>
<class name="com.sample.integration.ClassC"/>
<class name="com.sample.integration.ClassD"/>
<class name="com.sample.unit.ClassA"/>
<class name="com.sample.unit.ClassB"/>
</classes>
</test>
</suite>
You can make further configuration to this testNg XML as per your needs.

Parameterize #BeforeMethod method in TestNG

I have a base test class for my tests which does the initialisation work before each test.
Here is the code
public class BaseTestParameters {
MyObj myObj;
#DataProvider(name = "apiType")
public static Object[][] createData() {
return new Object[][] {{"type", "1"},{"type","2"}};
}
#BeforeMethod()
#Factory(dataProvider = "apiType")
public void setup(String type,String param) throws Exception {
myObj = createMyObject(param);
}
}
All my test classes extend this base class and they use the myObj for the tests.
myObj has two different ways of creation (depending on param).
All the tests will run twice . One with each way of constituting myObj.
How do I enable this scenario ?
Using #Factory annotation means I need to return Object[] from that method, but I don't have to return any test classes from that method.
You can use #Parameters annotation, but you have to specify values in testng,xml it means you have to have separate testng.xml for each set of parameters.
Here is example:
AppTest.java
public class AppTest {
#Parameters({"par1", "par2"})
#BeforeMethod()
public void setUp(String a, String b) {
System.out.println("a = [" + a + "], b = [" + b + "]");
}
#Test
public void testApp() {
}
}
testng.xml
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Suite1" verbose="1" >
<test name="Run1" >
<parameter name="par1" value="val"/>
<parameter name="par2" value="anotherval"/>
<packages>
<package name="dummy.java" />
</packages>
</test>
<test name="Run2" >
<parameter name="par1" value="newValue"/>
<parameter name="par2" value="yetAnotherVal"/>
<packages>
<package name="dummy.java" />
</packages>
</test>
</suite>

#AfterMethod being ignored when rerunning test in TestNG

I'm trying to build logic into my test suite so that if a test fails, it automatically gets rerun. When my test fails, it gets rerun as expected, but
my test suite contains an #AfterMethod which seems to be getting ignored when the test is getting rerun.
I've followed the solution given here:
https://www.softwaretestingmaterial.com/run-failed-test-cases-using-testng/
So I created the 2 classes:
package softwareTestingMaterial;
import org.testng.IRetryAnalyzer; import org.testng.ITestResult;
public class RetryFailedTestCases implements IRetryAnalyzer {
private int retryCnt = 0;
private int maxRetryCnt = 2;
public boolean retry(ITestResult result) {
if (retryCnt < maxRetryCnt) {
System.out.println("Retrying " + result.getName() + " again and the count is " + (retryCnt+1));
retryCnt++;
return true;
}
return false;
}
}
And
package softwareTestingMaterial;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import org.testng.IAnnotationTransformer;
import org.testng.IRetryAnalyzer;
import org.testng.annotations.ITestAnnotation;
public class RetryListenerClass implements IAnnotationTransformer {
#Override
public void transform(ITestAnnotation testannotation, Class testClass, Constructor testConstructor, Method testMethod) {
IRetryAnalyzer retry = testannotation.getRetryAnalyzer();
if (retry == null) {
testannotation.setRetryAnalyzer(RetryFailedTestCases.class);
}
}
}
My XML file for executing the tests looks as follows:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Test Suite 1">
<listeners>
<listener class-name="org.testng.reporters.EmailableReporter2" />
<listener class-name="CustomUtils.RetryListenerClass" />
</listeners>
<test name="Test 1">
<classes>
<class name="WebTests.CheckoutTestWeb"/>
</classes>
</test>
</suite>
When #Test throws exceptions, #AfterMethod may not run. To ensure #AfterMethod to be executed, add alwaysRun attribute which will look like #AfterMethod(alwaysRun = true)

testng - how to separate tests and supporting methods?

I am experimenting with testng. My goal is to have test methods in several classes and "supporting" methods for preparation and wrap-up of a bunch of tests in a separate class.
Another requirement is that in a test suite the supporting methods have to be called for multiple test parts. E.g. a first part containing testA and testB, and a second part containing testC and testD. This would result in the following steps:
support1, testA, testB, support2, support1, testC, testD, support2
My first approach that (partly) worked was to annotate all methods with #Test, use groups and define dependencies between groups, e.g. the test methods depend on a group "setUp", which is a group of one supporting method "support1" in the above example.
The problem with this approach is that the supporting methods count as tests, so the generated report shows the wrong number of "real" tests.
The next idea was to use #BeforeGroups and #AfterGroups, put the supporting methods in a group, and use group dependencies. The supporting methods should not be counted as tests any more. But I am stuck at the very beginning.
For example I tried
#BeforeGroups (groups = {"setUp"})
for a setup method in class Support, and
#Test(groups = { "TestA" }, dependsOnGroups = { "setUp" })
in a "real" test class. This results in the following (simplyfied) error:
[testng] DependencyMap::Method "TestClass.testSomething()[...]" depends on nonexistent group "setUp"
Why is group "setUp" nonexistent? Did I overlook something?
Or is there another approach which works?
Thanks for your help!
Edit:
The tests are started with Ant and I use a testng.xml like this:
<test name="TestA">
<groups>
<run>
<include name="setUp" />
<include name="TestA"/>
<include name="tearDown"/>
</run>
</groups>
<classes>
<class name="seleniumtest.test.technical.Support"/>
<class name="seleniumtest.test.business.TestClassA"/>
</classes>
</test>
<test name="TestB">
<groups>
<run>
<include name="setUp" />
<include name="TestB"/>
<include name="tearDown"/>
</run>
</groups>
<classes>
<class name="seleniumtest.test.technical.Support"/>
<class name="seleniumtest.test.business.TestClassB"/>
</classes>
</test>
I got the glitch!!
The problem is with the annotation
#Test(groups = { "TestA" }, dependsOnGroups = { "setUp" })
Basically your error message is trying to say that there is no #Test method with groupname as setUp!! Coming to your question, the solution is to modify annotation for the test method as below
#Test(groups = { "TestA" })
And in the support method modify the annotation
#BeforeGroups (groups = {"TestA"})
I ran a sample example with this set up
public class TestSupport {
#BeforeGroups(groups = { "sample","sample1" })
public void beforeTest() {
System.out.println("Before test");
}
#AfterGroups(groups = { "sample","sample1" })
public void afterTest() {
System.out.println("after test");
}
}
and with my Test class as
public class TestClassA {
#Test(groups = { "sample" })
public void superTestA() {
System.out.println("This is the actual test");
}
#Test(groups = { "sample" })
public void superTestB() {
System.out.println("This is the another test under sample group");
}
#Test(groups = { "sample1" })
public void superTest() {
System.out.println("This is another test");
}
}
and my testng.xml as shown below
<test name="sampletest" >
<groups>
<run>
<include name="sample" />
<include name="sample1" />
</run>
</groups>
<classes>
<class name="test.global.testng.TestClassA"/>
<class name="test.global.testng.TestSupport"/>
</classes>
</test>
Now this is how the test runs: beforeGroups-> superTestA/superTestB ->afterGroups and beforeGroups-> superTest -> afterGroups and closes off
I think I have come up with the solution I wanted.
What I need to use is #BeforeTest and #AfterTest instead of #BeforeGroups and #AfterGroups, respectively, in the support class:
#BeforeTest(groups = {"setUp"})
public void beforeTest() {[...]}
#AfterTest( groups = {"tearDown"})
public void afterTest() {[...]}
In the test class:
#Test(groups = { "TestA" })
public void testSomething() {[...]}
The dependsOnGroups is gone, as in Patton's approach.
The testng.xml is unchanged compared to my question. I.e. the tests can be configured in the testng.xml file, without having to change java code.
Moreover, this solution also gets rid of another problem of the BeforeGroups approach, at least as supposed by Patton (#Patton I do not mean to offend you).
With the latter a test using several test groups does not run as intended, because the beforeTest() method would be run before any of the groups. E.g. if you have the following test (extract of testng.xml):
<groups>
<run>
<include name="TestA"/>
<include name="TestB"/>
</run>
</groups>
... the resulting steps of execution are:
beforeTest(), TestA, beforeTest(), TestB, afterTest().
Using the solution with BeforeTest, you would have the following test:
<groups>
<run>
<include name="setUp" />
<include name="TestA"/>
<include name="TestB"/>
<include name="tearDown"/>
</run>
</groups>
... the resulting steps of execution are:
setUp = beforeTest(), TestA, TestB, tearDown = afterTest().
package com.test.MySample;
import org.testng.annotations.*;
public class TestNGTest1 {
#BeforeTest
public void BeforeTest() {
System.out.println("#BeforeTest");
}
#BeforeClass
public void BeforeClass() {
System.out.println("#BeforeClass");
}
#BeforeGroups (groups = {"My group"})
public void BeforeGroups() {
System.out.println("#BeforeGroups");
}
#BeforeGroups (groups = {"My group1"})
public void BeforeGroups1() {
System.out.println("#BeforeGroups1");
}
#AfterGroups (groups = {"My group1"})
public void AfterGroups1() {
System.out.println("#AfterGroups1");
}
#BeforeMethod
public void BeforeMethod() {
System.out.println("#BeforeMethod");
}
#Test(groups = {"My group"})
public void test1() {
System.out.println("test1");
}
#Test (groups = {"My group", "My group1"})
public void test2() {
System.out.println("test2");
}
#AfterMethod
public void AfterMethod() {
System.out.println("#AfterMethod");
}
#AfterGroups (groups = {"My group"})
public void AfterGroups() {
System.out.println("#AfterGroups");
}
#AfterClass
public void AfterClass() {
System.out.println("#AfterClass");
}
#AfterTest
public void AfterTest() {
System.out.println("#AfterTest");
}
}

Categories