Какая разница между DataProvider и Factory в TestNG?

Когда использовать DataProvider и когда использовать Factory?

Ответы

Ответ 1

TestNG factory используется для динамического создания экземпляров тестовых классов. Это полезно, если вы хотите запускать тестовый класс сколько угодно раз. Например, если у вас есть тест для входа в сайт, и вы хотите запустить этот тест несколько раз, тогда его легко использовать TestNG factory, где вы создаете несколько экземпляров тестового класса и запускаете тесты.

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;     
  }  

и класс тестирования теперь:

public class WebTest {     
  private int m_numberOfTimes;     
  public WebTest(int numberOfTimes) {      
    m_numberOfTimes = numberOfTimes;       
  }    

  @Test    
  public void testServer() {       
   //Code to test the application   
  }    
}    

Ваш testng.xml должен только ссылаться на класс, содержащий метод factory, так как сами тестовые экземпляры будут созданы во время выполнения:

<class name="WebTestFactory" />  

Метод factory может принимать параметры так же, как @Test и @Before/After, и он должен возвращать Object []. Возвращаемые объекты могут быть любого класса (не обязательно того же класса, что и класс factory).

В то время как датапарайдер используется для предоставления параметров для теста. Если вы предоставите dataprovider для теста, тест будет выполняться с разными значениями значений каждый раз. Это полезно для сценария, например, когда вы хотите войти в сайт с разными наборами имени пользователя и пароля каждый раз.

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;
    }

}

Ответ 2

Поставщик данных всегда создает один и тот же набор данных. Поэтому, если вам нужен экземпляр Person, вы всегда будете называть человека по имени Джон Уэйн из поставщика данных. Они предоставляют статические данные. Это полезно для тестовой параметризации, когда вы поставляете свой тест с двумя объектами - сначала это ввод метода, второй, который вы ожидаете.

Заводы позволяют динамически создавать тесты.. Они предоставляют динамические данные, такие как случайный контент, или если вы хотите вызвать какой-либо метод с параметрами diffrend.

Ответ 3

Factory реализация выполняет метод тестирования для каждого отдельного экземпляра тестового класса. Где, когда DataProvider выполняет метод тестирования для одного экземпляра тестового класса.

Ответ 4

TL;DR

  • @DataProvider → параметры для метода SINGLE
  • @Factory → params для методов ALL в классе

Позвольте мне начать с 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 getting annoying to specify the dataprovider everytime...
}

Но не с @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 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
       // ...
    }
}

Обратите внимание на две вещи при использовании Factory:

1) Вы должны указать конструктор no-arg или создать поля + методы статические. Подробнее здесь

2) С @DataProvider ваш @BeforeClass будет выполнен один раз. С помощью @Factory он будет выполнен с каждой итерацией.