When to use DataProvider and wh开发者_开发知识库en to use Factory ?
TestNG factory is used to create instances of test classes dynamically. This is useful if you want to run the test class any no of times. For example, if you have a test to login into a site and you want to run this test multiple times,then its easy to use TestNG factory where you create multiple instances of test class and run the tests.
public class WebTestFactory {
//createInstances method will create 10 objects of WebTest class
@Factory
public Object[] createInstances() {
Object[] result = new Object[10];
for (int i = 0; i < 10; i++) {
result[i] = new WebTest(i);
}
return result;
}
and the test class is now:
public class WebTest {
private int m_numberOfTimes;
public WebTest(int numberOfTimes) {
m_numberOfTimes = numberOfTimes;
}
@Test
public void testServer() {
//Code to test the application
}
}
Your testng.xml only needs to reference the class that contains the factory method, since the test instances themselves will be created at runtime:
<class name="WebTestFactory" />
The factory method can receive parameters just like @Test and @Before/After and it must return Object[]. The objects returned can be of any class (not necessarily the same class as the factory class).
Whereas, dataprovider is used to provide parameters to a test. If you provide dataprovider to a test, the test will be run taking different sets of value each time. This is useful for a scenario like where you want to login into a site with different sets of username and password each time.
public class DataProviderTest {
@Test(dataProvider= "data")
public void TestUltimatixFromExcelData(String userName,String password) {
WebDriver driver;
driver=new FirefoxDriver();
//Test to login into a site
}
@DataProvider(name="data")
public static Object[][] dataProviderTest() throws Exception{
Object[][] returnArray={new Object[]{"username1","password1"},new Object[]{"username2","password2"},new Object[]{"username3","password3"}
};
return returnArray;
}
}
Data provider always create the same data set. So if you need Person instance you will always get person called John Wayne from data provider. They provide static data. This is good for test parametrization when you supply your test with two objects - first is method input, second that you expect.
Factories allow you to create tests dynamically.. They provide dynamic data like random content or if you want call some method with diffrend parameters.
Factory implementation executes the test method for each individual instance of the test class. Where as DataProvider executes the test method for a single instance of the test class.
TLDR:
@DataProvider
-> params for a SINGLE method@Factory
-> params for ALL methods in a Class
Let me start with using DataProviders
:
public class VeryImportantTest {
@DataProvider
public static Object[][] numberProvider() {
return new Object[][]{
{1},
{2}
};
}
// DataProvider provides data to a SINGLE method
@Test(dataProvider = "numberProvider")
public void test1(int num){
Assert.assertNotEquals(3, num);
}
@Test(dataProvider = "numberProvider")
public void test2(int num){
// ...
}
@Test(dataProvider = "numberProvider")
public void test3(int num){
// ...
}
// Hmmm... I still have 10 tests to write here,
// and it's getting annoying to specify the dataprovider everytime...
}
But not with the @Factory
:
public class FactoryExample {
@Factory
public Object[] factoryMethod() {
return new Object[] {
new FactoryExample(0),
new FactoryExample(1)
};
}
private int number;
private FactoryExample(){}
private FactoryExample(int number) {
this.number = number;
}
// Now there's no need to specify dataproviders everywhere, nice
@Test
public void test1(){
Assert.assertNotEquals(3, number);
}
@Test
public void test2(){ // <-- No need to specify params in each method either
// ...
}
}
DO note two things when using Factory
:
1) You have to specify a no-arg constructor or make fields + methods static. See more here
2) With @DataProvider
, your @BeforeClass
will be executed once. With @Factory
it will be executed with every iteration.
精彩评论