Постачальник даних і TestNG XML: Параметризація в Selenium(Приклад)
Параметризація в Selenium
Параметризація в Selenium це процес параметризації тестових сценаріїв для передачі кількох даних у програму під час виконання. Це стратегія виконання, яка автоматично запускає тестові випадки кілька разів, використовуючи різні значення. Називається концепція, досягнута шляхом параметризації тестових сценаріїв Тестування на основі даних.
Тип параметризації в TestNG-
Щоб зробити параметризацію більш зрозумілою, ми розглянемо варіанти параметризації в одному з найпопулярніших фреймворків Selenium Webdriver – 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 | USA |
Бхупеш | Китай |
Ось приклад того, як це зробити БЕЗ параметрів
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>
ParameterWithTestNGФайл XML.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 Люкс (Примітка: Люкс)
Тепер параметри можна визначати на 2 рівнях
- Suite level – Параметри всередині тег TestNG XML-файл буде параметром рівня набору.
- Тестовий рівень — Параметри всередині тег XML-файлу тестування буде параметром рівня тестування.
Ось той самий тест із параметрами рівня набору
ПРИМІТКА: У випадку, якщо ім’я параметра однакове на рівні набору та на рівні тестування, параметр рівня тестування матиме перевагу над рівнем набору. Отже, у такому випадку всі класи всередині цього рівня тестування матимуть спільний доступ до перевизначеного параметра, а інші класи, які знаходяться за межами рівня тестування, спільно використовуватимуть параметр рівня набору.
Пошук і усунення несправностей
Issue #1 Значення параметра в testng.xml не можна привести до відповідного параметра методу тестування, це призведе до помилки.
Розглянемо наступний приклад
Тут атрибут 'author' дорівнює 'Guru99', який є рядком і у відповідному тестовому методі очікується ціле значення, тому тут ми отримаємо виняток.
Issue #2 Ваші @Parameters не мають відповідного значення в testing.xml.
Ви можете вирішити цю ситуацію, додавши @опціонально анотації у відповідному параметрі в методі тестування.
Випуск №3: Ви хочете перевірити кілька значень одного параметра за допомогою Testng.xml
Проста відповідь: це неможливо зробити! Ви можете мати кілька різних параметрів, але кожен параметр може мати лише одне значення. Це допомагає запобігти жорсткому кодуванню значень у сценарії. Це робить код придатним для повторного використання. Думайте про це як про файли конфігурації для вашого сценарію. Якщо ви хочете використовувати кілька значень для параметра, використовуйте DataProviders
Постачальник даних в TestNG
Постачальник даних в TestNG це метод, який використовується, коли користувачеві потрібно передати складні параметри. Необхідно створювати комплексні параметри Java такі як складні об’єкти, об’єкти з файлів властивостей або з бази даних можуть передаватися методом постачальника даних. Метод анотований @DataProvider і повертає масив об’єктів.
Параметри за допомогою Dataprovider
Анотація @Parameters проста, але для тестування з кількома наборами даних нам потрібно використовувати Data Provider.
Щоб заповнити тисячі веб-форм за допомогою нашої системи тестування, нам потрібна інша методологія, яка може надати нам дуже великий набір даних в одному потоці виконання.
Ця концепція, керована даними, досягається @DataProvider анотація в TestNG.
Він має лише один атрибут 'name'. Якщо ви не вкажете атрибут 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 @Тест анотація
Приклад коду
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.
У наступному прикладі
- Ми перевіряємо, чи ім’я методу є 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 групи А і Б
- Кожний метод тестування призначений для групи
- Якщо значення групи дорівнює А, повертається певний набір даних
- Якщо значення групи 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>
Підсумки
- Параметризація потрібно створити Тестування на основі даних.
- TestNG підтримують два види параметризації, використовуючи @Параметр+TestNG. Xml і використання@DataProvider
-
In @Параметр+TestNG. Xml параметри можна розмістити на рівні комплекту та тестовому рівні. Якщо
В обох місцях оголошено однакову назву параметра; параметр рівня тесту матиме перевагу над параметром рівня костюма.
- за допомогою @Parameter+TestNG.xml одночасно можна встановити лише одне значення, але @DataProvider повертає двовимірний масив Object.
- Якщо DataProvider присутній в іншому класі, то клас, де знаходиться тестовий метод,DataProvider повинно бути статичний метод.
- Підтримується два параметри DataProvider він має Метод та ITestContext.