<style>.lazy{display:none}</style>Dataprovider & TestNG XML: Параметризация в Selenium

Dataprovider & TestNG XML: Параметризация в Selenium

В этом учебном пособии вы узнаете:

Создавая программное обеспечение, мы всегда хотим, чтобы оно работало по-другому при разном наборе данных. Когда речь идет о тестировании одного и того же ПО, порой мы можем совершать ошибку, тестируя его только с одним набором данных. Здесь нам необходимо убедиться, что наша система принимает все наборы комбинаций, которые предполагается поддерживать. Чтобы упростить этот процесс, нам необходимо параметризовать наши тестовые скрипты.

Параметризация в Selenium

Параметризация в Selenium – это процесс параметризации тестовых сценариев с целью передачи нескольких данных приложению во время выполнения проверок. Это стратегия выполнения, которая автоматически запускает тестовые сценарии несколько раз, используя различные значения. Концепция, достигаемая путем параметризации тестовых сценариев, называется тестированием на основе данных (DDT – Data Driven Testing).

Подпишитесь на наш ТЕЛЕГРАМ КАНАЛ ПО АВТОМАТИЗАЦИИ ТЕСТИРОВАНИЯ

Тип параметризации в TestNG-

Чтобы сделать параметризацию более наглядной, мы рассмотрим возможности ее применения в одном из самых популярных фреймворков для Selenium Webdriver – TestNG.

Существует два способа, с помощью которых мы можем добиться параметризации в TestNG:

1. С помощью аннотации параметров и XML-файла TestNG.

2. С помощью аннотации DataProvider.

Способы, с помощью которых можно добиться параметризации в TestNG

Параметры из Testng.xml могут относиться к уровню набора или теста.

Параметр из DataProvider может принимать в качестве параметра Method и ITestContext.

Рассмотрим их подробнее.

Аннотация параметров в TestNG

Аннотация параметров в TestNG – это метод, используемый для передачи значений методам тестирования в качестве аргументов с использованием файла .xml. Пользователям может потребоваться передать значения методам тестирования во время выполнения. Метод аннотации @Parameters можно использовать в любом методе, имеющем аннотацию @Test, @Before, @After или @Factory.

Аннотация параметров с помощью Testng.xml

Выберите параметризацию с использованием аннотаций, если вы хотите иметь дело со сложностью и меньшим количеством входных комбинаций.

Давайте посмотрим, как это работает.

Тестовый сценарий:

Шаг 1. Запустите браузер и перейдите на сайт Google.com.

Шаг 2. Введите ключевое слово для поиска.

ввод ключевого слова в поисковую строку Google

Шаг 3. Убедитесь, что вводимое значение совпадает с данными, полученными при тестировании.

Шаг 4. Повторите шаги 2 и 3, пока не будут введены все значения.

Автор тестаSearchKey
Guru99India
KrishnaUSA
BhupeshChina

Приведем пример того, как это сделать БЕЗ параметров:

package parameters;

import org.testng.annotations.Test;
import org.testng.AssertJUnit;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;

public class NoParameterWithTestNGXML {
	String driverPath = "C:\\geckodriver.exe";
	WebDriver driver;
    
    @Test
    public void testNoParameter() throws InterruptedException{
        String author = "guru99";
        String searchKey = "india";
        
        System.setProperty("webdriver.gecko.driver", driverPath);        
        driver= new FirefoxDriver();
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
        
        driver.get("https://google.com");
        WebElement searchText = driver.findElement(By.name("q"));
        //Searching text in google text box
        searchText.sendKeys(searchKey);
        
        System.out.println("Welcome ->"+author+" Your search key is->"+searchKey);
                System.out.println("Thread will sleep now");
        
        Thread.sleep(3000);
        System.out.println("Value in Google Search Box = "+searchText.getAttribute("value") +" ::: Value given by input = "+searchKey);
        //verifying the value in google search box
        AssertJUnit.assertTrue(searchText.getAttribute("value").equalsIgnoreCase(searchKey));
}
}

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

Теперь давайте параметризируем это с помощью TestNG.

Для этого вам необходимо:

  • Создать XML-файл, в котором будут храниться параметры.
  • В тесте добавить аннотацию @Parameters.
Создание XML-файла, в котором будут храниться параметры

Приведем полный код.

Уровень тестирования TestNG.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="TestSuite" thread-count="3" >
<parameter name="author" value="Guru99" />
<parameter name="searchKey" value="India" />
<test name="testGuru">
<parameter name="searchKey" value="UK" />
<classes>
<class name="parameters.ParameterWithTestNGXML">
</class>
</classes>
</test>
</suite>

Файл ParameterWithTestNGXML.java

package parameters;

import org.testng.AssertJUnit;
import java.util.concurrent.TimeUnit;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;

import org.testng.annotations.Optional;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

public class ParameterWithTestNGXML {
	String driverPath = "C:\\geckodriver.exe";
	WebDriver driver;
    @Test
    @Parameters({"author","searchKey"})
    public void testParameterWithXML( @Optional("Abc") String author,String searchKey) throws InterruptedException{

        System.setProperty("webdriver.gecko.driver", driverPath);
        driver = new FirefoxDriver();
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
        driver.get("https://google.com");

        WebElement searchText = driver.findElement(By.name("q"));
        //Searching text in google text box
        searchText.sendKeys(searchKey);

        System.out.println("Welcome ->"+author+" Your search key is->"+searchKey);
        System.out.println("Thread will sleep now");
        Thread.sleep(3000);
        System.out.println("Value in Google Search Box = "+searchText.getAttribute("value") +" ::: Value given by input = "+searchKey);
        //verifying the value in google search box
        AssertJUnit.assertTrue(searchText.getAttribute("value").equalsIgnoreCase(searchKey));

}
}

Инструкции по запуску сценария: выберите XML-файл и запустите его как Test NG Suite.

Щелкните правой кнопкой мыши файл .xml -> Запустить от имени -> Testng Suite.

Запуск XML-файла как Test NG Suite

Теперь параметры могут быть определены на двух уровнях:

  1. Уровень набора: параметры внутри тега XML-файла TestNG будут являться параметрами уровня набора.
  2. Уровень тестирования: параметры внутри тега тестового XML-файла будут являться параметрами уровня тестирования.

Приведем тот же тест с параметрами уровня набора:

Тест с параметрами уровня набора

ПРИМЕЧАНИЕ: Если имя параметра одинаково на уровне набора и на уровне теста, то параметр уровня теста будет иметь преимущество перед параметром уровня набора. Таким образом, в этом случае все классы внутри тестового уровня будут совместно использовать переопределенный параметр, а другие классы, находящиеся вне тестового уровня, будут использовать параметр уровня набора.

Пример тестового уровня, показывающий, что если имя параметра одинаково на уровне набора и на уровне теста, то параметр уровня теста будет иметь преимущество перед параметром уровня набора

Поиск и устранение неисправностей

Проблема № 1 . Значение параметра в testng.xml не может быть типизировано в соответствующий параметр тестового метода, что приводит к ошибке.

Рассмотрим следующий пример:

Пример теста, в котором атрибут 'author' равен 'Guru99', что является строкой, а в соответствующем тестовом методе ожидается целочисленное значение, поэтому в этом случае выпадает исключение.

Здесь атрибут ‘author’ равен ‘Guru99’, что является строкой, а в соответствующем тестовом методе ожидается целочисленное значение, поэтому в этом случае мы получим исключение.

Проблема № 2. Ваши @Parameters не имеют соответствующего значения в файле testing.xml.

Эту ситуацию можно решить, добавив аннотацию @optional в соответствующий параметр метода тестирования.

Добавление аннотации @optional в соответствующий параметр метода тестирования

Проблема № 3 Вы хотите протестировать несколько значений одного и того же параметра с помощью Testng.xml.

Простой ответ: этого делать нельзя! Вы можете иметь несколько различных параметров, но каждый параметр может иметь только одно значение. Это помогает предотвратить жесткое кодирование значений в скрипте и делает код многократно используемым. Считайте, что это файлы конфигурации для вашего скрипта. Если вы хотите использовать несколько значений для параметра, используйте DataProviders.

Поставщик данных в TestNG

Провайдер данных в TestNG – это метод, используемый в тех случаях, когда пользователю необходимо передать сложные параметры. Сложные параметры должны быть созданы на Java, например, сложные объекты, объекты из файлов свойств или из базы данных могут быть переданы методом data provider. Метод аннотируется @DataProvider и возвращает массив объектов.

Параметры, использующие Dataprovider

Аннотация @Parameters проста, но для тестирования с несколькими наборами данных необходимо использовать Data Provider.

Чтобы заполнить тысячи веб-форм с помощью нашей среды тестирования, нам нужна другая методология, которая может дать нам очень большой набор данных в одном потоке выполнения.

Эта концепция управления данными достигается с помощью аннотации @DataProvider в TestNG.

Пример использования аннотации @DataProvider в TestNG

У него есть только один атрибут ‘name’. Если не указать этот атрибут, то имя DataProvider будет совпадать с именем соответствующего метода.

Поставщик данных возвращает двумерный объект JAVA методу тестирования, и метод тестирования будет вызван M раз в массиве объектов типа M*N. Например, если DataProvider возвращает массив из 2*3 объектов, то соответствующий тестовый пример будет вызываться 2 раза с 3 параметрами каждый раз.

Пример использования аннотации @DataProvider в TestNG

Полный пример:

package parameters;

import java.util.concurrent.TimeUnit;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;

import org.testng.Assert;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

public class ParameterByDataprovider {
    WebDriver driver;
    String driverPath = "C:\\geckodriver.exe";

    @BeforeTest
    public void setup(){
        //Create firefox driver object
         System.setProperty("webdriver.gecko.driver", driverPath);
         driver = new FirefoxDriver();
         driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
         driver.get("https://google.com");
    }
 
    /** Test case to verify google search box
     * @param author
     * @param searchKey
     * @throws InterruptedException
     */

    @Test(dataProvider="SearchProvider")
    public void testMethod(String author,String searchKey) throws InterruptedException{
    {
        WebElement searchText = driver.findElement(By.name("q"));
        //search value in google searchbox
        searchText.sendKeys(searchKey);
        System.out.println("Welcome ->"+author+" Your search key is->"+searchKey);
        Thread.sleep(3000);
        String testValue = searchText.getAttribute("value");
        System.out.println(testValue +"::::"+searchKey);
        searchText.clear();
        //Verify if the value in google search box is correct
        Assert.assertTrue(testValue.equalsIgnoreCase(searchKey));
    }
    }
    /**
     * @return Object[][] where first column contains 'author'
     * and second column contains 'searchKey'
     */

    @DataProvider(name="SearchProvider")
    public Object[][] getDataFromDataprovider(){
    return new Object[][] 
    	{
            { "Guru99", "India" },
            { "Krishna", "UK" },
            { "Bhupesh", "USA" }
        };

    }

}

Вызов DataProvider из другого класса

По умолчанию DataProvider находится в том же классе, что и тестовый метод, или в его базовом классе. Чтобы поместить его в какой-то другой класс, нам нужно сделать метод поставщика данных статическим, а в тестовом методе нам нужно добавить атрибут dataProviderClass в аннотации @Test.

Пример вызова DataProvider из другого класса

Пример кода:

Вид финального проекта

Параметр TestClassDataproviderWithClassLevel.java

package parameters;

import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.Assert;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;

public class ParameterDataproviderWithClassLevel {
    WebDriver driver;
    String driverPath = "C:\\geckodriver.exe";
    
 	@BeforeTest
    public void setup(){
 		System.setProperty("webdriver.gecko.driver", driverPath);
		driver = new FirefoxDriver();
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
        driver.get("https://google.com");
    }
   
    @Test(dataProvider="SearchProvider",dataProviderClass=DataproviderClass.class)
    public void testMethod(String author,String searchKey) throws InterruptedException{
        
        WebElement searchText = driver.findElement(By.name("q"));
        //Search text in google text box
        searchText.sendKeys(searchKey);
        System.out.println("Welcome ->"+author+" Your search key is->"+searchKey);
        Thread.sleep(3000);
        //get text from search box
        String testValue = searchText.getAttribute("value");
        System.out.println(testValue +"::::"+searchKey);
        searchText.clear();
        //verify if search box has correct value
        Assert.assertTrue(testValue.equalsIgnoreCase(searchKey));
   }
}

DataproviderClass.java

package parameters;

import org.testng.annotations.DataProvider;
public class DataproviderClass {
        @DataProvider(name="SearchProvider")
        public static Object[][] getDataFromDataprovider(){
            return new Object[][] {
                { "Guru99", "India" },
                { "Krishna", "UK" },
                { "Bhupesh", "USA" }
            };  
}}

Типы параметров в Dataprovider

Метод DataProvider поддерживает два типа параметров.

Method – если один и тот же поставщик данных должен вести себя по-разному при использовании другого метода тестирования, используйте параметр Method.

В следующем примере:

  • Мы проверяем, является ли имя метода testMethodA.
  • Если да, то возвращается один набор значений.
  • Иначе возвращается другой набор значений.
package parameters;

import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.Assert;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

public class ParameterByMethodInDataprovider{

    WebDriver driver;
    String driverPath = "C:\\geckodriver.exe";
     
    @BeforeTest
    public void setup(){
    	System.setProperty("webdriver.gecko.driver", driverPath);
    	driver = new FirefoxDriver();
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
        driver.get("https://google.com");
    }

    @Test(dataProvider="SearchProvider")
    public void testMethodA(String author,String searchKey) throws InterruptedException{
        
    	WebElement searchText = driver.findElement(By.name("q"));
        //Search text in search box
        searchText.sendKeys(searchKey);
        //Print author and search string
        System.out.println("Welcome ->"+author+" Your search key is->"+searchKey);
        Thread.sleep(3000);
        String testValue = searchText.getAttribute("value");
        System.out.println(testValue +"::::"+searchKey);
        searchText.clear();
        //Verify if google text box is showing correct value
        Assert.assertTrue(testValue.equalsIgnoreCase(searchKey));
    }
      
    @Test(dataProvider="SearchProvider")
    public void testMethodB(String searchKey) throws InterruptedException{
        {
        	WebElement searchText = driver.findElement(By.name("q"));
            //Search text in search box
            searchText.sendKeys(searchKey);
            //Print only search string
            System.out.println("Welcome ->Unknown user Your search key is->"+searchKey);
            Thread.sleep(3000);
            String testValue = searchText.getAttribute("value");
            System.out.println(testValue +"::::"+searchKey);
            searchText.clear();
            //Verify if google text box is showing correct value
            Assert.assertTrue(testValue.equalsIgnoreCase(searchKey));
        }
    }    
    /**
     * Here DataProvider returning value on the basis of test method name
     * @param m
     * @return
     **/

    @DataProvider(name="SearchProvider")
    public Object[][] getDataFromDataprovider(Method m){
        if(m.getName().equalsIgnoreCase("testMethodA")){
        return new Object[][] {
                { "Guru99", "India" },
                { "Krishna", "UK" },
                { "Bhupesh", "USA" }
            };}
        else{
        return new Object[][] {
                { "Canada" },
                { "Russia" },
                { "Japan" }
            };}       
    }
}

Ниже приведен результат:

TestNG: Parameterization using XML & DataProvider in Selenium

ITestContext – с его помощью можно создавать различные параметры для тестовых случаев на основе групп.

В реальной жизни можно использовать ITestContext для изменения значений параметров в зависимости от методов тестирования, хостов, конфигураций теста.

TestNG: Parameterization using XML & DataProvider in Selenium

В следующем примере кода:

  • У нас есть 2 группы A & B.
  • Каждый метод испытаний относится к группе.
  • Если значение группы равно A, то возвращается конкретный набор данных.
  • Если значение группы равно B, то возвращается другой набор данных.
package parameters;

import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.Assert;
import org.testng.ITestContext;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

public class ParameterByITestContextInDataprovider {
	WebDriver driver;
	String driverPath = "C:\\geckodriver.exe";
	@BeforeTest(groups={"A","B"})
	public void setup(){
		System.setProperty("webdriver.gecko.driver", driverPath);
		  	driver = new FirefoxDriver();
			driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
			driver.get("https://google.com");
	}
	
	@Test(dataProvider="SearchProvider",groups="A")
	public void testMethodA(String author,String searchKey) throws InterruptedException{
		{
		  //search google textbox
			WebElement searchText = driver.findElement(By.name("q"));
			//search a value on it
			searchText.sendKeys(searchKey);
			System.out.println("Welcome ->"+author+" Your search key is->"+searchKey);
			Thread.sleep(3000);
			String testValue = searchText.getAttribute("value");
			System.out.println(testValue +"::::"+searchKey);
			searchText.clear();
			//verify correct value in searchbox
			Assert.assertTrue(testValue.equalsIgnoreCase(searchKey));
	}
	}
	
	@Test(dataProvider="SearchProvider",groups="B")
	public void testMethodB(String searchKey) throws InterruptedException{
		{
		  //find google search box
			WebElement searchText = driver.findElement(By.name("q"));
			//search a value on it
			searchText.sendKeys(searchKey);
			System.out.println("Welcome ->Unknown user Your search key is->"+searchKey);
			Thread.sleep(3000);
			String testValue = searchText.getAttribute("value");
			System.out.println(testValue +"::::"+searchKey);
			searchText.clear();
			//verify correct value in searchbox
			Assert.assertTrue(testValue.equalsIgnoreCase(searchKey));
	}
	}
	
	/**
	 * Here the DAtaProvider will provide Object array on the basis on ITestContext
	 * @param c
	 * @return
	 */
	@DataProvider(name="SearchProvider")
	public Object[][] getDataFromDataprovider(ITestContext c){
	Object[][] groupArray = null;
		for (String group : c.getIncludedGroups()) {
		if(group.equalsIgnoreCase("A")){
			groupArray = new Object[][] { 
					{ "Guru99", "India" }, 
					{ "Krishna", "UK" }, 
					{ "Bhupesh", "USA" } 
				};
		break;	
		}
			else if(group.equalsIgnoreCase("B"))
			{
			groupArray = new Object[][] { 
						{  "Canada" }, 
						{  "Russia" }, 
						{  "Japan" } 
					};
			}
		break;
	}
	return groupArray;		
	}
}

Примечание: если вы запустите класс testng напрямую, то он сначала вызовет dataprovider, который не сможет получить информацию о группах, поскольку они будут недоступны. Если же вызвать этот класс через testng.xml, то информация о группах будет доступна в ITestContext. Используйте следующий XML для вызова теста:

<!DOCTYPE suite SYSTEM "http://beust.com/testng/testng-1.0.dtd" >
<suite name="test-parameter">

  <test name="example1">

    <groups>
        <run>
            <include name="A" />
        </run>
    </groups>

    <classes>
       <class
        name="parameters.ParameterByITestContextInDataprovider" />
    </classes>

  </test>


  <test name="example2">

    <groups>
        <run>
            <include name="B" />
        </run>
    </groups>

    <classes>
       <class
        name="parameters.ParameterByITestContextInDataprovider" />
    </classes>

  </test>

</suite>

Выводы

  • Параметризация необходима для создания тестирования, управляемого данными.
  • TestNG поддерживает два вида параметризации – с помощью @Parameter+TestNG.xml и с помощью@DataProvider.
  • В @Parameter+TestNG.xml параметры могут быть размещены на уровне набора и на уровне теста. Если в обоих местах объявлено одно и то же имя параметра, то параметр уровня тестирования будет иметь преимущество перед параметром уровня набора.
  • При использовании @Parameter+TestNG.xml одновременно можно задать только одно значение, но @DataProvider возвращает двухмерный массив Object.
  • Если DataProvider присутствует в классе, отличном от класса, в котором находится тестовый метод, то DataProvider должен быть статическим методом.
  • Существует два параметра, поддерживаемых DataProvider – это Method и ITestContext.

Перевод статьи «Dataprovider & TestNG XML: Parameterization in Selenium(Example)».

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *