Andmepakkuja TestNG: Selenium Parameetristamise näide
⚡ Nutikas kokkuvõte
Parameetristamine sisse Selenium käivitab ühte testimismeetodit korduvalt erinevate andmekogumite vastu, muutes ühe skripti andmepõhiseks katvuseks. TestNG pakub selleks kahte mehhanismi: testng.xml-failil põhinevat @Parameters annotatsiooni ja kahemõõtmelise objektimassiivi tagastavat @DataProvider annotatsiooni.

Tarkvara loomisel soovime alati, et see töötaks erinevate andmekogumitega korrektselt. Kui asi puudutab testimine Selle tarkvara puhul ei piisa ühe andmekogumi kontrollimisest. Peame veenduma, et süsteem aktsepteerib kõiki kombinatsioone, mida see eeldatavasti toetab. Selleks peame oma testiskriptid parameetriseerima. Siin tulebki mängu parameetriseerimine.
Parameetristamine sisse Selenium
Parameetristamine sisse Selenium on testskriptide parameetrite muutmise protsess, et edastada rakendusele käitusajal mitut teavet. See on täitmisstrateegia, mis käivitab testjuhtumeid automaatselt mitu korda, kasutades erinevaid väärtusi. Testskriptide parameetritega saavutatud kontseptsiooni nimetatakse Andmepõhine testimine.
Parameetri tüüp sisse TestNG
Parameetristamise selgemaks muutmiseks vaatame läbi parameetristamise valikud ühes populaarseimas raamistikus Selenium Veebidraiver — TestNG.
Seal on kahel viisil mille abil saame saavutada parameetrite muutmise TestNG:
- Abiga Parameetrite märkus ja TestNG XML faili.
- Abiga DataProvider märkus.
Ülaltoodud diagramm võtab jaotuse kokku: testng.xml-i parameetreid saab deklareerida komplekti või testi tasandil, samas kui DataProvideri parameeter saab aktsepteerida Method ja ITestContext omaette argumendina. Uurime neid lähemalt.
Parameetrid Annotatsioon sisse TestNG
Parameetrid Annotatsioon sisse TestNG on meetod, mida kasutatakse väärtuste edastamiseks testmeetoditele argumentidena .xml-faili abil. Kasutajatel võib olla vaja edastada väärtused testmeetoditele käitusaja jooksul. Annotatsioonimeetodit @Parameters saab kasutada mis tahes meetodis, millel on annotatsioon @Test, @Before, @After või @Factory.
Parameetrite annotatsioon rakendusega Testng.xml
Valige annotatsioonide abil parameetriseerimine, kui te ei soovi keerukusega tegeleda ja sisendkombinatsioonide arv on väike.
Vaatame, kuidas see toimib.
Testi stsenaarium
Step 1) Käivitage brauser ja minge aadressile GoogleCom
Step 2) Sisestage otsingusõna
Step 3) Veenduge, et sisestatud väärtus on sama, mis meie testandmetes esitatud väärtus
Step 4) Korda samme 2 ja 3, kuni kõik väärtused on sisestatud
| Testi autor | Otsinguklahv |
|---|---|
| Guru99 | India |
| Krishna | USA |
| Bhupesh | Hiina |
Siin on näide, kuidas seda teha ilma parameetrid:
package parameters; import org.testng.annotations.Test; import org.testng.AssertJUnit; import java.time.Duration; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.firefox.FirefoxDriver; public class NoParameterWithTestNGXML { WebDriver driver; @Test public void testNoParameter() throws InterruptedException { String author = "guru99"; String searchKey = "india"; driver = new FirefoxDriver(); driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10)); driver.get("https://google.com"); WebElement searchText = driver.findElement(By.name("q")); // Searching text in the Google text box searchText.sendKeys(searchKey); System.out.println("Welcome ->" + author + " Your search key is->" + searchKey); Thread.sleep(3000); System.out.println("Value in Google Search Box = " + searchText.getDomProperty("value") + " ::: Value given by input = " + searchKey); // Verifying the value in the Google search box AssertJUnit.assertTrue(searchText.getDomProperty("value").equalsIgnoreCase(searchKey)); } }
⚠️ Selenium 4. aasta märkus: Selle näite algversioonis olevad kolm rida ei kompileeru enam või on praeguses versioonis aegunud. Selenium Vabastatakse. System.setProperty("webdriver.gecko.driver", …) on ebavajalik alates Selenium 4.6 edasi, sest Selenium Haldur lahendab draiveri binaarfaili automaatselt. implicitlyWait(10, TimeUnit.SECONDS) ülekoormus eemaldati Selenium 4 ja asendatud järgmisega implicitlyWait(Duration.ofSeconds(10)). getAttribute() oli aegunud aastal Selenium 4.27, seega tekstikasti lugemine kasutab getDomProperty("value")Iga allolev näide rakendab samu kolme parandust.
Uurige ülaltoodud näidet ja kujutage ette, kui keeruliseks kood muutub, kui seda korrata kolme sisendkombinatsiooni korral.
Nüüd parameetriseerime selle, kasutades TestNGSelleks peate tegema järgmist:
- Looge XML-fail, mis salvestab parameetrid
- Testis lisa märkus @Parameters
Siin on täielik kood.
Testi tase TestNG. Xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE suite SYSTEM "https://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>
Parameeter KoosTestNGXML.java fail
package parameters; import org.testng.AssertJUnit; import java.time.Duration; 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 { WebDriver driver; @Test @Parameters({"author", "searchKey"}) public void testParameterWithXML(@Optional("Abc") String author, String searchKey) throws InterruptedException { driver = new FirefoxDriver(); driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10)); driver.get("https://google.com"); WebElement searchText = driver.findElement(By.name("q")); // Searching text in the Google text box searchText.sendKeys(searchKey); System.out.println("Welcome ->" + author + " Your search key is->" + searchKey); Thread.sleep(3000); System.out.println("Value in Google Search Box = " + searchText.getDomProperty("value") + " ::: Value given by input = " + searchKey); // Verifying the value in the Google search box AssertJUnit.assertTrue(searchText.getDomProperty("value").equalsIgnoreCase(searchKey)); } }
Skripti käivitamiseks valige XML-fail ja käivitage see skriptina. TestNG kohta.
Paremklõpsake .xml-failil -> Käivita nimega -> TestNG Sviit (Märkus: Sviit)
Parameetreid saab defineerida kahel tasandil:
- Sviiditasand — parameetrid seespool
<suite>silt TestNG XML-failid on komplekti tasemel parameetrid. - Testi tase — parameetrid seespool
<test>silt TestNG XML-failid on testitaseme parameetrid.
Siin on sama test komplekti tasemel parameetritega:
MÄRKUS: Kui parameetri nimi on komplekti tasemel ja testi tasemel sama, on testi taseme parameeter eelistatud komplekti taseme esimesele. Sellisel juhul jagavad kõik sellel testi tasemel olevad klassid ülekirjutatud parameetrit ja klassid väljaspool seda testi taset jätkavad komplekti taseme parameetri kasutamist.
Probleemid
1. probleem: Parameetri väärtus failis testng.xml, mida ei saa vastava testimismeetodi parameetrile tüübistata, tekitab vea.
Kaaluge järgmist näidet:
Siin on atribuut „autor” võrdne väärtusega „Guru99', mis on string, samas kui vastav testimismeetod ootab täisarvulist väärtust, seega tekib erand.
2. probleem: Sinu @Parameters väärtusel puudub testng.xml failis vastav väärtus.
Selle saate lahendada, lisades @Valikuline märkus katsemeetodi vastava parameetri suhtes.
3. probleem: Sa tahad testida sama parameetri mitut väärtust, kasutades testng.xml-i.
Lihtne vastus on see, et seda ei saa teha. Teil võib olla mitu erinevat parameetrit, kuid iga parameeter saab sisaldada ainult ühte väärtust. See hoiab ära väärtuste skripti kõvakodeerimise ja hoiab koodi korduvkasutatavana – mõelge sellest kui oma skripti konfiguratsioonifailist. Kui vajate ühe parameetri jaoks mitut väärtust, kasutage hoopis DataProviderit.
Andmepakkuja sisse TestNG
Andmepakkuja sisse TestNG on meetod, mida kasutatakse siis, kui kasutaja peab edastama keerulisi parameetreid. Keerulised parameetrid tuleb luua Java — andmepakkuja meetod saab edastada keerukaid objekte, objekte atribuutifailidest või objekte andmebaasist. Meetod annoteeritakse @DataProvideriga ja tagastab objektide massiivi.
Parameetrid Dataprovideri abil
@Parameters annotatsioon on lihtne, aga mitme andmekogumiga testimiseks peame kasutama andmepakkujat.
Tuhandete veebivormide täitmiseks meie testimisraamistiku abil vajame teistsugust metoodikat, mis suudab ühe teostusvoo käigus pakkuda väga suurt andmekogumit.
See andmepõhine kontseptsioon saavutatakse järgmiselt: @DataProvider annotatsioon sisse TestNG.
Sellel on ainult üks atribuut, 'nimi'Kui te ei määra atribuuti „name”, on andmepakkuja nimi sama, mis vastava meetodi nimi.
Andmepakkuja tagastab kahemõõtmeline Java objekt testimismeetodile ja testimismeetodit kutsutakse M korda M×N objektimassiivi jaoks. Näiteks kui DataProvider tagastab 2×3 objektist koosneva massiivi, kutsutakse vastav testjuhtum välja 2 korda 3 parameetriga iga kord.
Täielik näide
package parameters; import java.time.Duration; 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; @BeforeTest public void setup() { // Create the Firefox driver object driver = new FirefoxDriver(); driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10)); driver.get("https://google.com"); } /** Test case to verify the Google search box */ @Test(dataProvider = "SearchProvider") public void testMethod(String author, String searchKey) throws InterruptedException { WebElement searchText = driver.findElement(By.name("q")); // Search value in the Google search box searchText.sendKeys(searchKey); System.out.println("Welcome ->" + author + " Your search key is->" + searchKey); Thread.sleep(3000); String testValue = searchText.getDomProperty("value"); System.out.println(testValue + "::::" + searchKey); searchText.clear(); // Verify if the value in the Google search box is correct Assert.assertTrue(testValue.equalsIgnoreCase(searchKey)); } /** * @return Object[][] where the first column contains 'author' * and the second column contains 'searchKey' */ @DataProvider(name = "SearchProvider") public Object[][] getDataFromDataprovider() { return new Object[][] { { "Guru99", "India" }, { "Krishna", "UK" }, { "Bhupesh", "USA" } }; } }
Kutsuge DataProvider erinevast klassist
Vaikimisi asub andmepakkuja (DataProvider) samas klassis kui testmeetod või selle baasklassis. Selle paigutamiseks teise klassi muutke andmepakkuja meetod staatiline ja lisage atribuut dataProviderClass Euroopa @Test märkus.
Code Näide
TestClass ParameterDataproviderWithClassLevel.java
package parameters; import java.time.Duration; 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; @BeforeTest public void setup() { driver = new FirefoxDriver(); driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10)); 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 the Google text box searchText.sendKeys(searchKey); System.out.println("Welcome ->" + author + " Your search key is->" + searchKey); Thread.sleep(3000); // Get text from the search box String testValue = searchText.getDomProperty("value"); System.out.println(testValue + "::::" + searchKey); searchText.clear(); // Verify if the search box has the 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" } }; } }
Andmepakkuja parameetrite tüübid
DataProvider meetod toetab kahte tüüpi parameetreid.
Meetod — kui sama DataProvider peaks erinevate testimismeetodite puhul käituma erinevalt, kasutage parameetrit Method.
Järgmises näites:
- Kontrollime, kas meetodi nimi on testMethodA
- Kui jah, tagastage üks väärtuste komplekt
- Vastasel juhul tagastage teine väärtuste komplekt
package parameters; import java.lang.reflect.Method; import java.time.Duration; 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; @BeforeTest public void setup() { driver = new FirefoxDriver(); driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10)); driver.get("https://google.com"); } @Test(dataProvider = "SearchProvider") public void testMethodA(String author, String searchKey) throws InterruptedException { WebElement searchText = driver.findElement(By.name("q")); searchText.sendKeys(searchKey); // Print author and search string System.out.println("Welcome ->" + author + " Your search key is->" + searchKey); Thread.sleep(3000); String testValue = searchText.getDomProperty("value"); System.out.println(testValue + "::::" + searchKey); searchText.clear(); Assert.assertTrue(testValue.equalsIgnoreCase(searchKey)); } @Test(dataProvider = "SearchProvider") public void testMethodB(String searchKey) throws InterruptedException { WebElement searchText = driver.findElement(By.name("q")); searchText.sendKeys(searchKey); // Print only the search string System.out.println("Welcome ->Unknown user Your search key is->" + searchKey); Thread.sleep(3000); String testValue = searchText.getDomProperty("value"); System.out.println(testValue + "::::" + searchKey); searchText.clear(); Assert.assertTrue(testValue.equalsIgnoreCase(searchKey)); } /** The DataProvider returns values based on the test method name */ @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" } }; } } }
Siin on väljund:
ITestContext — seda saab kasutada rühmade põhjal erinevate parameetrite loomiseks testidele.
Tegelikkuses saate ITestContexti abil parameetrite väärtusi muuta vastavalt testimismeetoditele, hostidele või testimiskonfiguratsioonidele.
Järgmises koodinäites:
- Meil on kaks gruppi, A ja B.
- Iga katsemeetod määratakse rühmale
- Kui rühma väärtus on A, tagastatakse üks andmekogum
- Kui rühma väärtus on B, tagastatakse teine andmekogum.
package parameters; import java.time.Duration; 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; @BeforeTest(groups = {"A", "B"}) public void setup() { driver = new FirefoxDriver(); driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10)); driver.get("https://google.com"); } @Test(dataProvider = "SearchProvider", groups = "A") public void testMethodA(String author, String searchKey) throws InterruptedException { WebElement searchText = driver.findElement(By.name("q")); searchText.sendKeys(searchKey); System.out.println("Welcome ->" + author + " Your search key is->" + searchKey); Thread.sleep(3000); String testValue = searchText.getDomProperty("value"); System.out.println(testValue + "::::" + searchKey); searchText.clear(); Assert.assertTrue(testValue.equalsIgnoreCase(searchKey)); } @Test(dataProvider = "SearchProvider", groups = "B") public void testMethodB(String searchKey) throws InterruptedException { WebElement searchText = driver.findElement(By.name("q")); searchText.sendKeys(searchKey); System.out.println("Welcome ->Unknown user Your search key is->" + searchKey); Thread.sleep(3000); String testValue = searchText.getDomProperty("value"); System.out.println(testValue + "::::" + searchKey); searchText.clear(); Assert.assertTrue(testValue.equalsIgnoreCase(searchKey)); } /** The DataProvider supplies an Object array based on ITestContext */ @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; } }
Märge: Kui käivitate TestNG klassi otse kutsudes kutsub see esmalt andmepakkuja ja pakkuja ei saa grupiteavet lugeda, kuna grupid pole veel saadaval. Klassi kutsumine testng.xml kaudu muudab grupiteabe kättesaadavaks ITestContexti kaudu. Testi käivitamiseks kasutage järgmist XML-i:
<!DOCTYPE suite SYSTEM "https://testng.org/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>
Mõlemad mehhanismid on nüüd kaetud, seega on praktiline küsimus, millise poole pöörduda.
@Parameetrid vs @Andmepakkuja: Kumba kasutada?
Need kaks lähenemisviisi ei ole omavahel asendatavad. Otsus taandub sellele, mitu väärtuskombinatsiooni test vajab ja kust need väärtused pärinevad.
| Kriteerium | @Parameetrid + testng.xml | @DataProvider |
|---|---|---|
| Väärtused parameetri kohta | Täpselt üks | Piiramatu arv ridu |
| Andmeallikas | Staatiline tekst XML-failis | Java kood, Excel, CSV, andmebaas, API |
| Toetatud tüübid | Väärtuste tüübimuundumine stringist | mistahes Java objekt |
| Testikutsed | Üks kord konfiguratsiooni kohta | Üks kord andmerea kohta |
| Andmete muutmine nõuab | XML-faili redigeerimine | Lähtekoodi redigeerimine, sageli ei pea uuesti kompileerima |
| Sobib kõige paremini | Keskkonna ja konfiguratsiooni väärtused, näiteks brauser, URL, volitused | Andmepõhine testimine paljude sisendkombinatsioonide korral |
Praktikas kasutab enamik pakette mõlemat: @Parameters kannab keskkonnasätteid, mis püsivad kogu tsükli vältel muutumatuna, ja @DataProvider annab varieeruvad äriandmed. Kui andmestik kasvab kõvakodeeritud massiivist välja, on järgmine samm selle lugemine arvutustabelist.
Kuidas lugeda testandmeid Exceli failist DataProvideri abil
Kõvakodeeritud massiivid lõpetavad skaleerimise, kui testijad, kes ei kirjuta, Java vajadus andmeid säilitada. Ridade viimine arvutustabelisse eraldab testandmed testloogikast, mis on praktiline vorm andmepõhine testimineApache POI loeb töövihikut ja DataProvider teisendab iga rea üheks testikutseks.
- Lisage sõltuvus. Sisaldama
org.apache.poi:poi-ooxmloma Mavenis või Gradle ehitada. Seeooxmlartefakt haldab .xlsx-vormingut; tavalinepoiloeb ainult pärand .xls-faile. - Loo töövihik. Paiguta päiserida ritta 0 ja üks testjuhtum rea kohta selle alla, kusjuures iga testimeetodi argumendi kohta on üks veerg.
- Loe leht massiivi. Määrake Object[][] suurus ridade ja lahtrite arvu põhjal, et uued read saaksid valitud ilma koodi muutmata.
- Tagastage see teenusepakkujalt. Testimeetodi signatuur jääb täpselt samaks.
import java.io.FileInputStream; import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.testng.annotations.DataProvider; public class ExcelDataProvider { @DataProvider(name = "SearchProvider") public Object[][] readSearchData() throws Exception { FileInputStream file = new FileInputStream("src/test/resources/testdata.xlsx"); Workbook workbook = new XSSFWorkbook(file); Sheet sheet = workbook.getSheetAt(0); // Skip the header row, so subtract one from the physical row count int rows = sheet.getLastRowNum(); int cols = sheet.getRow(0).getPhysicalNumberOfCells(); Object[][] data = new Object[rows][cols]; for (int i = 1; i <= rows; i++) { for (int j = 0; j < cols; j++) { data[i - 1][j] = sheet.getRow(i).getCell(j).getStringCellValue(); } } workbook.close(); file.close(); return data; } }
💡 Näpunäide: Helista getStringCellValue() ainult tekstina vormindatud lahtrites. Numbriline lahter viskab IllegalStateException, mis on kõige levinum tõrge, kui arvutustabel sisaldab ID-sid või summasid. Kasutage DataFormatter , et lugeda iga lahtritüüpi stringina või lülitada sisse cell.getCellType() ja teisendada selgesõnaliselt.
Kuna andmed on eksternaliseeritud, muutub saja testi lisamine pigem arvutustabeli redigeerimiseks kui koodi muutmiseks ning sama pakkuja saab süsteemi kaudu edastada mitu testiklassi. dataProviderClass varem näidatud atribuut.
















