Parameterize #BeforeMethod method in TestNG - java

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>

Related

IAnnotation transform method is not disabling the test in testng

Here my intention is , Based on the before method condition the #Test method needs to enabled or disabled But in the below code even though I am passing the test case name its not getting skipped ? Can anyone suggest me solution?
I need the BeforeTestMethod to check some logic in my actual code and based on that I have to enable the #Test in the class file
public class ListnerClass implements IAnnotationTransformer {
public static String testName;
public void transform(ITestAnnotation iTest, Class testClass, Constructor testConstructor, Method method) {
if(method.getName().equalsIgnoreCase(testName)) {
iTest.setEnabled(false);
}
}
public class TestNGTest3 {
#BeforeMethod
public void setUp(Method result) {
System.out.println("This is the before Method getting name "+result.getName());
if(result.getName().contains("3"))
{
ListnerClass.testName=result.getName();
}
}
#Test
public void testMethod3() {
System.out.println("This is the Method of Method");
}
#Test
public void testMethod4() {
System.out.println("Hi");
}
}
TestNG.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name=" Regression Suite">
<listeners>
<listener class-name="com.listners.ListnerClass" />
</listeners>
<test thread-count="1" name="Test">
<classes>
<class name="com.test.TestNGTest3" />
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
Output:
This is the before Method getting name testMethod3
This is the Method of Method
This is the before Method getting name testMethod4
Hi
Finally I have achieve my intention with the help of the below post.
Why is throw new SkipException() skipping all my methods?
Here is an working sample:
public class TestClassTest {
static String name;
static int i=0;
`public static String testmethod() {
List<String> list= new ArrayList<String>();
list.add("Raja");
list.add("Raju");
list.add("Raj");
name=list.get(i);
i++;
return name;
}
public class DependsOnMethodClass extends TestClassTest {
#BeforeMethod()
public void beforecaller(Method m) {
if(!testmethod().equals("Raju")) {
System.out.println("This is the method going to be skipped
"+m.getName());
throw new SkipException("Data provided is not matching");
}
else {
System.out.println("This is the method not skipped"+m.getName());
}
}
#Test
public void getCall() {
System.out.println("This is the getCall method");
}
#Test()
public void getCall1() {
System.out.println("This is the getCall1 method");
}
}
Update of TestNG xml: (Important Change)
Adding the parameter configfailurepolicy="continue" will continue the test even we
are throwing skip exception.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite" configfailurepolicy="continue">
<test thread-count="5" name="Test">
<classes>
<class name="com.testng.newsuite.DependsOnMethodClass"/>
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
Output:
This is the method going to be skipped getCall
This is the method not skipped getCall1
This is the getCall1 method

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.

How to order test cases using priority and groups annotation?

there are some flows that i want to test through automation. i am using selenium , maven, java and testNG. i have 2 different class. Let say class A and Class B.
public class A (){
#Test(groups="flow1",priority=0)
public void method a1()
{
}
#Test(groups="flow1".priority=2)
public void method a2()
{
}
#Test
public void method a3()
{
}
and 2nd class is class B
public class b (){
#Test(groups="flow1", priority=1)
public void method b1()
{
}
#Test
public void method b2()
{
}
#Test
public void method b3()
{
}
now i want to achieve flow like below
method a1()
method b1()
method a2()
i had try in this way through testng.xml
<test name="test1">
<groups>
<run>
<include name="flow1" />
</run>
</groups>
<classes>
<class name="a" />
<class name="b" />
</classes>
</test>
but i am not getting that output. it will run only one test cases and then it is skipping others.
i had try also some different way but i am not getting my goal.
can anybody help me
thanks
in your testng.xml just add group-by-instances="true"
<suite thread-count="2" verbose="10" name="testSuite" parallel="tests">
<test verbose="2" name="MytestCase" group-by-instances="true">
<classes>
<class name="com.A.classA" />
<class name="com.A.classB" />
</classes>
</test>
</suite>

Same test class multiple <test> not run

I want to run same test method as part of multiple . TestNG runs my test method only once irrespective. Paramters are different in both cases. Any pointers on how I can achieve this is greatly appreciated
public class Test1 extends TestBase{
#Test
public void test1(){
System.out.println("This si test1");
}
}
public class TestBase {
#Parameters({ "param1" })
#BeforeMethod
public void setup(#Optional("VCHS") String param1) {
System.out.println("the parameter is "+param1);
}
#Parameters({ "param1" })
#BeforeTest(groups="VC2-UI",alwaysRun=true)
protected void baseSetUpVC2EndPoint(#Optional("VC2") String param1){
System.out.println("This is base"+param1);
}
#Parameters({ "param1" })
#BeforeTest(groups="VC1-UI")
protected void baseSetUpVC1EndPoint(#Optional("VC1") String param1){
System.out.println("This is base and "+param1);
}
}
<suite name="Testing" verbose="1" configfailurepolicy="continue">
<test name="VC2-UI">
<parameter name="param1" value="VC2"/>
<classes>
<class name="Test1"></class>
</classes>
</test>
<test name="VC1-UI">
<parameter name="param1" value="VC1"/>
<classes>
<class name="Test1"></class>
</classes>
</test>
</suite>
You can use invocationCount annotation.

testng "groups" testing fails

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.

Categories