Доставчик на данни и TestNG XML: Параметризация в Selenium(Пример)

Докато създаваме софтуер, винаги ни се иска той да работи по различен начин с различен набор от данни. Когато става въпрос за Тестване един и същ софтуер, не можем да бъдем несправедливи да го тестваме само с един набор от данни. Тук отново трябва да проверим дали нашата система приема всички комбинации, които се очаква да поддържат. За целта трябва да параметризираме нашите тестови скриптове. Тук идва Параметризацията в картината.

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

Параметризация в Selenium е процес за параметризиране на тестовите скриптове, за да се предадат множество данни към приложението по време на изпълнение. Това е стратегия за изпълнение, която автоматично изпълнява тестови случаи няколко пъти, използвайки различни стойности. Концепцията, постигната чрез параметризиране на тестовите скриптове, се нарича Тестване, управлявано от данни.

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

За да направим параметризирането по-ясно, ще преминем през опциите за параметризиране в една от най-популярните рамки за Selenium уебдрайвер – TestNG.

Има два начина чрез които можем да постигнем параметризация в TestNG

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

    Тип на параметризирането в TestNG

  2. С помощта на Доставчик на данни анотация.

    Тип на параметризирането в TestNG

Тип на параметризирането в TestNG

Параметрите от Testng.xml могат да бъдат пакетно или тестово ниво

Параметърът от DataProvider може да приема Method и ITestContext като параметър.

Нека ги проучим подробно –

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

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

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

Изберете параметризация с помощта на анотации, когато искате да се справите със сложността и броят на входните комбинации е по-малък.

Нека видим как работи това

Сценарий на теста

Стъпка 1) Стартирайте браузъра и отидете на Google.com

Стъпка 2) Въведете ключова дума за търсене

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

Стъпка 3) Уверете се, че въведената стойност е същата като тази, предоставена от нашите тестови данни

Стъпка 4) Повторете 2 и 3, докато не бъдат въведени всички стойности

Автор на теста SearchKey
Guru99 Индия
Krishna САЩ
Бхупеш Китай

Ето пример как да го направите БЕЗ параметри

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

Ето пълния код

Тестово ниво 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 файла и стартирайте като тест NG Suite

Щракнете с десния бутон върху .xml файл -> Изпълни като -> Testng Апартамент (Забележка: апартамент)

ParameterWithTestNGXML.java файл

Сега параметрите могат да се дефинират на 2 нива

  1. Suite level – Параметрите вътре в етикет на TestNG XML файлът ще бъде параметър на ниво пакет.
  2. Тестово ниво — Параметрите вътре в етикетът на тестовия XML файл ще бъде параметър за тестово ниво.

Ето същия тест с параметри на ниво пакет

ParameterWithTestNGXML.java файл

ЗАБЕЛЕЖКА: В случай, че името на параметъра е едно и също на ниво пакет и ниво на тест, тогава параметърът на ниво тест ще получи предпочитание пред нивото на пакет. Така че в този случай всички класове в това тестово ниво ще споделят отменения параметър, а други класове, които са извън тестовото ниво, ще споделят параметъра на ниво пакет.

ParameterWithTestNGXML.java файл

Отстраняване на проблеми

Брой #1 Стойността на параметъра в testng.xml не може да бъде преобразувана към параметъра на съответния тестов метод, това ще доведе до грешка.

Помислете за следния пример

Отстраняване на неизправности

Тук атрибутът „автор“ е равен на „Guru99', което е низ и в съответния тестов метод очаква цяло число, така че тук ще получим изключение.

Брой #2 Вашите @Parameters нямат съответстваща стойност в testing.xml.

Можете да разрешите тази ситуация, като добавите @по избор анотация в съответния параметър в метода за изпитване.

Отстраняване на неизправности

Проблем # 3: Искате да тествате множество стойности на един и същ параметър с помощта на Testng.xml

Простият отговор е, че това не може да се направи! Можете да имате няколко различни параметъра, но всеки параметър може да има само една стойност. Това помага да се предотврати твърдото кодиране на стойности в скрипта. Това прави кода многократно използваем. Мислете за това като за конфигурационни файлове за вашия скрипт. Ако искате да използвате няколко стойности за параметър, използвайте DataProviders

Доставчик на данни в TestNG

Доставчик на данни в TestNG е метод, използван, когато потребителят трябва да предаде сложни параметри. Комплексните параметри трябва да бъдат създадени от Java като сложни обекти, обекти от файлове със свойства или от база данни могат да бъдат предавани чрез метода на доставчика на данни. Методът е анотиран от @DataProvider и връща масив от обекти.

Параметри, използващи Dataprovider

@Parameters анотацията е лесна, но за да тестваме с множество набори от данни, трябва да използваме Data Provider.

За да попълним хиляди уеб формуляри, използвайки нашата рамка за тестване, се нуждаем от различна методология, която може да ни даде много голям набор от данни в един поток на изпълнение.

Тази концепция, управлявана от данни, се постига чрез @Доставчик на данни анотация в TestNG.

Параметри, използващи Dataprovider

Има само един атрибут "име". Ако не посочите атрибута name, тогава името на DataProvider ще бъде същото като името на съответния метод.

Доставчикът на данни връща двуизмерен JAVA обект към тестовия метод и тестовия метод, ще извика M пъти в M*N тип обектен масив. Например, ако DataProvider върне масив от 2*3 обекта, съответният тестов случай ще бъде извикан 2 пъти с 3 параметъра всеки път.

Параметри, използващи Dataprovider

Пълен пример

Параметри, използващи Dataprovider

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 in @Тест анотация.

Извикване на DataProvider от различен клас

Code Пример

Извикване на DataProvider от различен клас

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 трябва да се държи различно с различен тестов метод, използвайте метод параметър.

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

В следния пример,

  • Проверяваме дали името на метода е 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" }
            };}       
    }
}

Ето изхода

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

ITestContext– Може да се използва за създаване на различни параметри за тестови случаи въз основа на групи.

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

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

В следния пример на код

  • Имаме 2 групи А и Б
  • Всеки тестов метод е присвоен на група
  • Ако стойността на групата е 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>

Oбобщение

  • Параметризиране се изисква да се създаде Тестване, управлявано от данни.
  • TestNG поддържа два вида параметризация, използвайки @Параметър+TestNG. Xml и използване@Доставчик на данни
  • In @Параметър+TestNG. Xml параметрите могат да бъдат поставени на ниво пакет и ниво на тестване. Ако

    Едно и също име на параметър е декларирано и на двете места; параметърът за тестово ниво ще получи предимство пред параметъра за ниво на костюма.

  • използвайки @Parameter+TestNG.xml само една стойност може да бъде зададена в даден момент, но @DataProvider връща 2d масив от Object.
  • Ако DataProvider присъства в различния клас, тогава класът, в който се намира тестовият метод,Доставчик на данни трябва да бъде статичен метод.
  • Има два параметъра, поддържани от Доставчик на данни сте Начин на доставка намлява ITestContext.

Обобщете тази публикация с: