Доставчик на данни и TestNG XML: Параметризация в Selenium(Пример)
Параметризация в Selenium
Параметризация в Selenium е процес за параметризиране на тестовите скриптове, за да се предадат множество данни към приложението по време на изпълнение. Това е стратегия за изпълнение, която автоматично изпълнява тестови случаи няколко пъти, използвайки различни стойности. Концепцията, постигната чрез параметризиране на тестовите скриптове, се нарича Тестване, управлявано от данни.
Тип параметризация в TestNG-
За да направим параметризирането по-ясно, ще преминем през опциите за параметризиране в една от най-популярните рамки за Selenium уебдрайвер – TestNG.
Има два начина чрез които можем да постигнем параметризация в TestNG
Параметрите от Testng.xml могат да бъдат пакетно или тестово ниво
Параметърът от DataProvider може да приема Method и ITestContext като параметър.
Нека ги проучим подробно –
Параметри Анотация в TestNG
Параметри Анотация в TestNG е метод, използван за предаване на стойности към тестовите методи като аргументи, използвайки .xml файл. Може да се наложи потребителите да предадат стойностите на тестовите методи по време на изпълнение. Методът за анотация @Parameters може да се използва във всеки метод с анотация @Test, @Before, @After или @Factory.
Анотация на параметрите с Testng.xml
Изберете параметризация с помощта на анотации, когато искате да се справите със сложността и броят на входните комбинации е по-малък.
Нека видим как работи това
Сценарий на теста
Стъпка 1) Стартирайте браузъра и отидете на Google.com
Стъпка 2) Въведете ключова дума за търсене
Стъпка 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
<?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 Апартамент (Забележка: апартамент)
Сега параметрите могат да се дефинират на 2 нива
- Suite level – Параметрите вътре в етикет на TestNG XML файлът ще бъде параметър на ниво пакет.
- Тестово ниво — Параметрите вътре в етикетът на тестовия XML файл ще бъде параметър за тестово ниво.
Ето същия тест с параметри на ниво пакет
ЗАБЕЛЕЖКА: В случай, че името на параметъра е едно и също на ниво пакет и ниво на тест, тогава параметърът на ниво тест ще получи предпочитание пред нивото на пакет. Така че в този случай всички класове в това тестово ниво ще споделят отменения параметър, а други класове, които са извън тестовото ниво, ще споделят параметъра на ниво пакет.
Отстраняване на проблеми
Брой #1 Стойността на параметъра в testng.xml не може да бъде преобразувана към параметъра на съответния тестов метод, това ще доведе до грешка.
Помислете за следния пример
Тук атрибутът „автор“ е равен на „Guru99', което е низ и в съответния тестов метод очаква цяло число, така че тук ще получим изключение.
Брой #2 Вашите @Parameters нямат съответстваща стойност в testing.xml.
Можете да разрешите тази ситуация, като добавите @по избор анотация в съответния параметър в метода за изпитване.
Проблем # 3: Искате да тествате множество стойности на един и същ параметър с помощта на Testng.xml
Простият отговор е, че това не може да се направи! Можете да имате няколко различни параметъра, но всеки параметър може да има само една стойност. Това помага да се предотврати твърдото кодиране на стойности в скрипта. Това прави кода многократно използваем. Мислете за това като за конфигурационни файлове за вашия скрипт. Ако искате да използвате няколко стойности за параметър, използвайте DataProviders
Доставчик на данни в TestNG
Доставчик на данни в TestNG е метод, използван, когато потребителят трябва да предаде сложни параметри. Комплексните параметри трябва да бъдат създадени от Java като сложни обекти, обекти от файлове със свойства или от база данни могат да бъдат предавани чрез метода на доставчика на данни. Методът е анотиран от @DataProvider и връща масив от обекти.
Параметри, използващи Dataprovider
@Parameters анотацията е лесна, но за да тестваме с множество набори от данни, трябва да използваме Data Provider.
За да попълним хиляди уеб формуляри, използвайки нашата рамка за тестване, се нуждаем от различна методология, която може да ни даде много голям набор от данни в един поток на изпълнение.
Тази концепция, управлявана от данни, се постига чрез @Доставчик на данни анотация в TestNG.
Има само един атрибут "име". Ако не посочите атрибута name, тогава името на DataProvider ще бъде същото като името на съответния метод.
Доставчикът на данни връща двуизмерен JAVA обект към тестовия метод и тестовия метод, ще извика M пъти в M*N тип обектен масив. Например, ако DataProvider върне масив от 2*3 обекта, съответният тестов случай ще бъде извикан 2 пъти с 3 параметъра всеки път.
Пълен пример
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 @Тест анотация.
Code Пример
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 трябва да се държи различно с различен тестов метод, използвайте метод параметър.
В следния пример,
- Проверяваме дали името на метода е 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" }
};}
}
}
Ето изхода
ITestContext– Може да се използва за създаване на различни параметри за тестови случаи въз основа на групи.
В реалния живот можете да използвате ITestContext, за да променяте стойностите на параметрите въз основа на тестови методи, хостове, конфигурации на теста.
В следния пример на код
- Имаме 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.
















