Учебники

33) Параметризация

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

Здесь идет Параметризация на картинке. Чтобы передать несколько данных приложению во время выполнения, нам необходимо параметризовать наши тестовые сценарии.

Эта концепция, которую мы достигаем путем параметризации, называется  Data Driven Testing.

В этом уроке вы узнаете

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

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

Есть  два способа  достижения параметризации в TestNG

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

    TestNG: параметризация с использованием XML и DataProvider в Selenium

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

    TestNG: параметризация с использованием XML и DataProvider в Selenium

TestNG: параметризация с использованием XML и DataProvider в Selenium

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

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

Давайте изучим их подробно —

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

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

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

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

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

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

TestNG: параметризация с использованием XML и DataProvider в Selenium

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

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

Автор теста SearchKey
Guru99 Индия
Кришна Соединенные Штаты Америки
Bhupesh Китай

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

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

Исследование, приведенный выше пример. Только представьте, насколько сложным станет код, когда мы сделаем это для 3 входных комбинаций.

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

Для этого вам нужно будет

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

TestNG: параметризация с использованием XML и DataProvider в Selenium

Вот полный код

Тестовый уровень 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 File

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

}
}

Instructions to run the script, select the XML file and Run as Test NG Suite

Right Click on .xml file -> Run as -> Testng Suite (Note : Suite)

TestNG: параметризация с использованием XML и DataProvider в Selenium

Now, parameters can be defined at 2 levels

  1. Suite level – The parameters inside the <suite> tag of TestNG XML file will be a suite level parameter.
  2. Test Level — The parameters inside the <Test> tag of testing XML file will be a Test level parameter.

Here is the same test with suite level parameters

TestNG: параметризация с использованием XML и DataProvider в Selenium

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

TestNG: параметризация с использованием XML и DataProvider в Selenium

Поиск проблемы

Ошибка # 1  Значение параметра в testng.xml нельзя типизировать с соответствующим параметром метода тестирования, это вызовет ошибку.

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

TestNG: параметризация с использованием XML и DataProvider в Selenium

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

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

Вы можете решить эту ситуацию, добавив  аннотацию @option   в соответствующем параметре в методе теста.

TestNG: параметризация с использованием XML и DataProvider в Selenium

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

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

Параметры с использованием Dataprovider

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

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

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

TestNG: параметризация с использованием XML и DataProvider в Selenium

У него только один  атрибут «имя» . Если вы не укажете атрибут name, тогда имя DataProvider будет таким же, как имя соответствующего метода.

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

TestNG: параметризация с использованием XML и DataProvider в Selenium

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

TestNG: параметризация с использованием XML и DataProvider в Selenium

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 находится в том же классе, где находится метод test, или его базовый класс. Чтобы поместить его в какой-то другой класс, нам нужно сделать метод провайдера данных статическим, а в тестовом методе нам нужно добавить атрибут  dataProviderClass  в  аннотации  @Test .

TestNG: параметризация с использованием XML и DataProvider в Selenium

Пример кода

TestNG: параметризация с использованием XML и DataProvider в Selenium

TestClass ParameterDataproviderWithClassLevel.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.

Метод. Если один и тот  же  DataProvider должен вести себя по-разному при использовании другого метода тестирования, используйте параметр Method.

TestNG: параметризация с использованием XML и DataProvider в Selenium

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

  • Мы проверяем, если имя метода 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: параметризация с использованием XML и DataProvider в Selenium

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

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

TestNG: параметризация с использованием XML и DataProvider в 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, он сначала вызовет поставщик данных, который не может получить информацию о группах, поскольку группы недоступны. Но вместо этого, если вы вызовете этот класс через 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>

Резюме :

  • Параметризация требуется для создания Data Driven Testing .
  • TestNG поддерживает два вида параметризации, используя @ Parameter + TestNG.xml и используя @DataProvider
  • В @ Parameter + TestNG.xml параметры могут быть размещены на уровне набора и уровня тестирования. Если

    Одно и то же имя параметра объявляется в обоих местах; Параметр уровня теста получит преимущество над параметром уровня костюма.

  • используя @ Parameter + TestNG.xml, можно установить только одно значение за раз, но @DataProvider возвращает 2d массив Object .
  • Если DataProvider присутствует в другом классе, чем в классе, в котором находится тестовый метод, DataProvider должен быть статическим методом .
  • DataProvider поддерживает два параметра : Method и ITestContext.