Difference between @Factory and @DataProvider annotations

Both the annotations belong to TestNg testing framework. Many people get confused while reading about these two annotations that why and where we have to use these two?

Very basic difference between these two are-

@DataProvider- DataProvider annotations parameterize the particular test method and execute the test number of times based on data provided by DataProvider method. So if two parameters are there then test will execute twice.

@Factory- Factory executes all the test methods present inside any test class file using separate instance of the respective class.

Still confused???

Let’s have look on some programs-

@DataProvider
public Object[][] message(){
return new Object [][]{{“Mayank” , new Integer (321)}, {“Dileep”, new Integer (282)}};
}

@Test (dataProvider=”message”)
public void PrintMsg(String name, Integer id){
System.out.println(“Names are: “+name+” “+id);
}

As above program states that there are two data and if I run this program result will be-

Result1

So, it proves that if you increase the number of data in message method, PrintMsg method will execute same number of times.

Now we will see Factory and how it is different from DataProvider-

public class TestFactory {
@Factory
public Object[] factorymethod(){
return new Object[]{new DPandFactoryExaple(), new DPandFactoryExaple()};
}}

public class DPandFactoryExaple {
@DataProvider
public Object[][] message(){
return new Object [][]{{“Mayank” , new Integer (321)}, {“Dileep”, new Integer (282)}};
}
@Test (dataProvider=”message”)
public void PrintMsg(String name, Integer id){
System.out.println(“Names are: “+name+” “+id);
}
@Test
public void PrintSuccessfullMessage(){
System.out.println(“Print the successfull message”);
}}

So if we see DPandFactoryExaple class then you will find there are two @Test methods and 1 @Test method has to execute twice and 1 @Test method has to execute once. So there should be 3 messages.

Now if you see @Factory method it is calling the same class twice and in that case there should be 6 messages. See the results below-

Result2

So did it clear the doubts?? No, then comment it out we will discuss it.

 

Advertisements

How to run Selenium + TestNG script from Command Line?

This is an alternate way to execute our selenium script from command prompt. Here, I am considering few points-

  • Your project is already set-up in Eclipse
  • Project already has testng.xml file.
  • All selenium and other third party jar files are located under project home folder (lib folder).
  • You are able to execute your script by running testng.xml file.

cmd3

If above conditions are matching then very few steps are there to execute same script from command prompt. Follow the below steps-

Open Command Prompt and Go to Project home directory-

CMD

Set the class path and libraries path by running below command-

set classpath=<Project Home Path>\bin;<Project Home Path>\lib\*

cmd1

Now run the testng.xml file by running below command-

java org.testng.TestNG testng.xml—-Make sure “org.testng.TestNG” TestNG word should have ‘T’ and ‘NG’ in caps.

CMD2

I hope it would help people to run testng.xml file from the command prompt.

Difference between @BeforeTest and @BeforeClass annotation in TestNg

Ah ha…a topic which confused me also to understand the difference between BeforeTest and BeforeClass annotation. When we read first time it looks same and then we think if it is same then why TestNg included it. So clue is, it is not same and included for two different purposes-

We will go through again with these annotations definition which is available under TestNg official site and that are-

@BeforeTest-The annotated method will be run before any test method belonging to the classes inside the tag is run.

@BeforeClass-The annotated method will be run before the first test method in the current class is invoked.

Have a look on below example-

public class FirstClass {
@BeforeTest
public void BT(){
System.out.println(“This is before test”);
}
@AfterTest
public void AT(){
System.out.println(“This is after test”);
}
@Test (priority =-20)
public void fctestmethod(){
System.out.println(“This is First Class test method.”);
}}

————————————————————————————————-

public class SecondClass {
@BeforeClass
public void BC(){
System.out.println(“This is before class”);
}
@AfterClass
public void AC(){
System.out.println(“This is after class”);
}
@Test (priority =-19)
public void sctestFirstmethod(){
System.out.println(“This is Second Class first test method.”);
}
@Test (priority =-18)
public void sctestSecondmethod(){
System.out.println(“This is Second Class second test method.”);
}}

————————————————————————————————-

————————————————————————————————-

[TestNG] Running:
D:\Training\BeforeTestndClassExample\testng.xml

This is before test
This is First Class test method.
This is before class
This is Second Class first test method.
This is Second Class second test method.
This is after class
This is after test

===============================================
My test suite
Total tests run: 3, Failures: 0, Skips: 0
===============================================

————————————————————————————————-

Hints:

  • <test> tag is wrapped by @BeforeTest and @AfterTest
  • <class> tag is wrapped by @BeforeClass and @AfterClass

So if we see in test result @BeforeTest method executed very first and then lowest priority @Test method (fctestmethod). In third position @BeforeClass method executed which was defined in Second Class. Now question is why it got executed at third position, so answer is-

  • <class> tag is wrapped by @BeforeClass and @AfterClass

and

@BeforeClass-The annotated method will be run before the first test method in the current class is invoked.

As @Before and After was defined in Second Class therefore it got executed when testng.xml invoked Second Class class file not before any test.

Significance of alwaysRun=true @Test annotation property.

alwaysRun=true property informs the system that TestNg should run the test method if depends on @Test method fails also. Basically it helps to achieve the soft dependency, the feature of TestNG which helps to execute the testng test methods in order. Below is the code example:

AlwaysRun

So above code states that system will execute the Close() method if Login method fails also.

Dependencies with TestNG

‘TestNG’ is a framework that built with different set of APIs that facilitates many testing needs. It has variety of features that makes ‘TestNG’ more convenient than ‘JUnit’ framework. Among all the features, TestNG has ‘dependencies’ feature that gives the facility to determine the @Test annotation methods order. For the dependencies, TestNG uses ‘dependsOnMethods’ option for @Test annotation.

Hold on, should not confuse with ‘order’ word. I do not have meant that with this feature you could create your own order to run the Test methods.

TestNG dependency feature does not give guarantee on the order on which the methods depended upon will be run, however it guaranteed that TestNG will run all the @Test methods before the method which contains the ‘dependsOnMethods’ option.

In TestNG, we can achieve dependencies in two ways-

  • With Annotation.
  • With XML

It has two types also-

  • Hard Dependency
  • Soft Dependency

Hard dependency says that if depended upon @Test method fails then TestNG will skip the depended @Test method.

Soft dependency says that TestNG will run the depended @Test method if depended upon @Test methods fails also, however depended @Test method should have ‘alwaysRun=true’ option.

Hard Dependency Instance:

import org.testng.annotations.Test;

public class dependsOnMethods {

@Test

public void sub (){

int a = 7-3;

System.out.println(“sub “+a);

}

@Test (dependsOnMethods={“sub”})

public void div (){

int a = 10/2;

System.out.println(“div “+a);

}

@Test

public void add (){

int a = 7+3;

System.out.println(“add “+a);

}

}

[TestNG] Running:

C:\Users\testng-eclipse-224652221\testng-customsuite.xml

add 10

sub 4

div 5

PASSED: add

PASSED: sub

PASSED: div

TestNG runs all the @Test methods before the ‘div’ method.

Soft Dependency Instance:

import org.testng.annotations.Test;

public class dependsOnMethods {

@Test

public void sub (){

int a = 7-3;

System.out.println(“sub “+a);

}

@Test (alwaysRun= true, dependsOnMethods={“sub”})

public void div (){

int a = 10/2;

System.out.println(“div “+a);

}

@Test

public void add (){

int a = 7+3;

System.out.println(“add “+a);

}

}

TestNG will run the ‘div’ method if ‘sub’ methods fails also.

With Annotation Instance:

import org.testng.annotations.Test;

public class dependsOnMethods {

@Test

public void sub (){

int a = 7-3;

System.out.println(“sub “+a);

}

@Test (dependsOnMethods={“sub”})

public void div (){

int a = 10/2;

System.out.println(“div “+a);

}

@Test

public void add (){

int a = 7+3;

System.out.println(“add “+a);

}

}

‘div’ method is depended upon the ‘sub’ method. So whenever TestNG runs this class, all methods will run before the ‘div’ method.

[TestNG] Running:

C:\Users\testng-eclipse-224652221\testng-customsuite.xml

add 10

sub 4

div 5

PASSED: add

PASSED: sub

PASSED: div

With XML Instance:

To achieve dependency with XML, we should have testing.xml file. In testing xml file we can specify our group dependency with tag.

<test name=”regression suite”>

<groups>

<dependencies>

<group name=”sanity”/>

<group name=”functional” depends-on=”Sanity” />

<group name=”integration” depends-on=”Sanity  functional” />

</dependencies>

</groups>

</test>

The <depends-on> attribute contains a space-separated list of groups.