Adatszolgáltató TestNG: Selenium Paraméterezési példa
⚡ Okos összefoglaló
Paraméterezés be Selenium egyetlen tesztmetódust futtat ismételten különböző adathalmazokon, így egyetlen szkriptet adatvezérelt lefedettséggé alakít. TestNG két mechanizmust kínál erre: a testng.xml által támogatott @Parameters annotációt, és a @DataProvider annotációt, amely egy kétdimenziós objektumtömböt ad vissza.
Amikor szoftvert fejlesztünk, mindig azt szeretnénk, hogy az helyesen működjön a különböző adathalmazokkal. Ami a következőket illeti tesztelés az adott szoftver esetében egyetlen adathalmaz ellenőrzése nem elegendő. Ellenőriznünk kell, hogy a rendszer elfogad-e minden olyan kombinációt, amelyet várhatóan támogat. Ehhez paraméterezni kell a tesztszkripteket. Itt jön képbe a paraméterezés.
Paraméterezés be Selenium
Paraméterezés be Selenium egy folyamat a tesztszkriptek paraméterezésére annak érdekében, hogy futás közben több adatot továbbítson az alkalmazásnak. Ez egy olyan végrehajtási stratégia, amely automatikusan futtatja a teszteseteket különböző értékek használatával. A tesztszkriptek paraméterezésével elért koncepciót ún Adatvezérelt tesztelés.
A paraméterezés típusa TestNG
A paraméterezés jobb megértése érdekében áttekintjük a paraméterezési lehetőségeket az egyik legnépszerűbb keretrendszerben, amely a következőket kínálja: Selenium WebDriver — TestNG.
Vannak két út amivel paraméterezést érhetünk el TestNG:
- A Paraméterek megjegyzése és a TestNG XML fájlt.
- A DataProvider kommentár.
A fenti ábra összefoglalja a felosztást: a testng.xml paraméterei deklarálhatók csomag- vagy tesztszinten, míg egy DataProvider paramétere elfogadhatja a következőket: Method és a ITestContext mint önálló érvet. Vizsgáljuk meg őket részletesen.
Paraméterek Annotáció be TestNG
Paraméterek Annotáció be TestNG egy olyan metódus, amely értékeket ad át a tesztmetódusoknak argumentumként egy .xml fájl használatával. A felhasználóknak futásidőben kell átadniuk az értékeket a tesztmetódusoknak. A @Parameters annotációs metódus bármely olyan metódusban használható, amely @Test, @Before, @After vagy @Factory annotációval rendelkezik.
Paraméter-annotáció a Testng.xml-lel
Válassza az annotációkkal történő paraméterezést, ha nem szeretne bonyolultsággal foglalkozni, és a bemeneti kombinációk száma kicsi.
Lássuk, hogyan működik ez.
Teszt forgatókönyv
Step 1) Indítsd el a böngészőt, és menj ide: Google.com
Step 2) Írjon be egy keresési kulcsszót
Step 3) Ellenőrizd, hogy a beírt érték megegyezik-e a tesztadatok által megadott értékkel.
Step 4) Ismételje meg a 2. és 3. lépést, amíg az összes értéket be nem adta
| Tesztszerző | SearchKey |
|---|---|
| Guru99 | India |
| Krishna | USA |
| Bhupesh | Kína |
Íme egy példa arra, hogyan kell csinálni nélkül paraméterek:
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-os megjegyzés: A példa eredeti verziójában szereplő három sor már nem fordul le, vagy elavult a jelenlegi verzióban. Selenium kiadásokban. System.setProperty("webdriver.gecko.driver", …) felesleges attól Selenium 4.6-tól felfelé, mert Selenium A kezelő automatikusan feloldja az illesztőprogram bináris fájlját. implicitlyWait(10, TimeUnit.SECONDS) a túlterhelést eltávolították Selenium 4 és helyébe a következő lép: implicitlyWait(Duration.ofSeconds(10)). getAttribute() elavult volt Selenium 4.27, tehát egy szövegdoboz olvasása a következőt használja: getDomProperty("value")Az alábbi példák mindegyike ugyanazt a három korrekciót alkalmazza.
Tanulmányozd a fenti példát, és képzeld el, milyen bonyolulttá válik a kód, ha ezt három bemeneti kombinációra megismételjük.
Most paraméterezzük a következővel: TestNGEhhez a következőket kell tennie:
- Hozzon létre egy XML fájlt, amely tárolja a paramétereket
- A tesztben add hozzá a @Parameters annotációt.
Itt a teljes kód.
Teszt szint 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>
ParaméterWithTestNGXML.java fájl
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)); } }
A szkript futtatásához jelölje ki az XML fájlt, és futtassa azt egy TestNG tovább.
Jobb klikk az .xml fájlon -> Futtatás másként -> TestNG Lakosztály (Megjegyzés: Lakosztály)
A paraméterek két szinten definiálhatók:
- Lakosztályszint — a paraméterek a
<suite>a címkéje TestNG Az XML fájlok csomag szintű paraméterek. - Teszt szint — a paraméterek a
<test>a címkéje TestNG Az XML fájlok teszt szintű paraméterek.
Itt ugyanaz a teszt csomag szintű paraméterekkel:
JEGYZET: Ha a paraméter neve megegyezik a csomag szintjén és a teszt szinten, akkor a tesztszintű paraméter elsőbbséget élvez a csomag első szintjével szemben. Ebben az esetben az adott tesztszinten belüli összes osztály megosztja a felülírott paramétert, és a tesztszinten kívüli osztályok továbbra is a csomagszintű paramétert használják.
Hibaelhárítás
1. probléma: A testng.xml fájlban található paraméterérték, amelyet nem lehet típusátalakítani a megfelelő tesztmetódus paraméterére, hibát dob.
Tekintsük a következő példát:
Itt a „szerző” attribútum egyenlő a következővel:Guru99', ami egy karakterlánc, míg a megfelelő tesztmetódus egész értéket vár, így kivétel keletkezik.
2. probléma: A @Parameters paraméterednek nincs megfelelő értéke a testng.xml fájlban.
Ezt úgy oldhatod meg, hogy hozzáadod a @Opcionális megjegyzés a vizsgálati módszer megfelelő paraméteréhez.
3. probléma: Ugyanazon paraméter több értékét szeretnéd tesztelni a testng.xml használatával.
Az egyszerű válasz az, hogy ezt nem lehet megtenni. Több különböző paramétered is lehet, de mindegyik paraméter csak egyetlen értéket tartalmazhat. Ez megakadályozza az értékek szkriptbe való fix kódolását, és lehetővé teszi a kód újrafelhasználhatóságát – képzeld el úgy, mint a szkript konfigurációs fájlját. Ha egy paraméterhez több értékre van szükséged, használj inkább egy DataProvidert.
Adatszolgáltató be TestNG
Adatszolgáltató be TestNG egy olyan metódus, amelyet akkor használnak, amikor a felhasználónak összetett paramétereket kell átadnia. Az összetett paramétereket a következőből kell létrehozni: Java — összetett objektumok, tulajdonságfájlokból származó objektumok vagy adatbázisból származó objektumok adhatók át az adatszolgáltató metódussal. A metódus @DataProvider annotációval van ellátva, és egy objektumtömböt ad vissza.
Paraméterek a Dataprovider használatával
A @Parameters annotáció egyszerű, de több adathalmazzal való teszteléshez adatszolgáltatót kell használnunk.
Ahhoz, hogy több ezer webes űrlapot kitölthessünk a tesztelési keretrendszerünkkel, egy másik módszertanra van szükségünk, amely egyetlen végrehajtási folyamatban képes nagyon nagy adathalmazt előállítani.
Ez az adatvezérelt koncepció a következőképpen valósul meg: @DataProvider megjegyzés be TestNG.
Csak egy van benne attribútum, 'név'Ha nem adjuk meg a name attribútumot, a DataProvider neve megegyezik a megfelelő metódus nevével.
Egy adatszolgáltató visszaadja egy kétdimenziós Java tárgy a tesztmetódushoz, és a tesztmetódus M-szer kerül meghívásra egy M×N objektumtömb esetén. Például, ha a DataProvider 2×3 objektumból álló tömböt ad vissza, a megfelelő teszteset 2-szer kerül meghívásra, minden alkalommal 3 paraméterrel.
Teljes példa
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" } }; } }
A DataProvider meghívása különböző osztályokból
Alapértelmezés szerint egy DataProvider a tesztmetódussal azonos osztályban, vagy annak alaposztályában található. Egy másik osztályba helyezéséhez az adatszolgáltató metódust úgy kell beállítani, hogy statikus és add hozzá az attribútumot dataProviderClass hoz @Teszt kommentár.
Code Példa
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" } }; } }
Paraméterek típusai az adatszolgáltatóban
A DataProvider metódus kétféle paramétert támogat.
Módszer – ha a azonos A DataProvidernek eltérően kell viselkednie a különböző tesztelési metódusok esetén, használja a Method paramétert.
A következő példában:
- Ellenőrizzük, hogy a metódus neve testMethodA-e.
- Ha igen, akkor adjon vissza egy értékkészletet
- Egyébként egy másik értékkészletet ad vissza
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" } }; } } }
Itt van a kimenet:
ITestContext — ez felhasználható csoportok alapján különböző paraméterek létrehozására tesztesetekhez.
A való életben az ITestContext segítségével változtathatja a paraméterek értékeit a tesztelési metódusok, hosztok vagy tesztkonfigurációk alapján.
A következő kódpéldában:
- Két csoportunk van, A és B.
- Minden vizsgálati módszer egy csoporthoz van rendelve
- Ha a csoport értéke A, akkor egy adathalmazt ad vissza.
- Ha a csoport értéke B, akkor egy másik adathalmazt ad vissza.
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; } }
Jegyzet: Ha futtatod a TestNG osztály közvetlenül meghívja, először az adatszolgáltatót hívja meg, és a szolgáltató nem tudja beolvasni a csoportinformációkat, mert a csoportok még nem érhetők el. Az osztály testng.xml-en keresztüli meghívása elérhetővé teszi a csoportinformációkat az ITestContext-en keresztül. A teszt futtatásához használja a következő XML-t:
<!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>
Mindkét mechanizmust lefedtük, így a gyakorlati kérdés az, hogy melyiket ragadjuk meg.
@Parameters vs. @DataProvider: Melyiket használjuk?
A két megközelítés nem felcserélhető. A döntés azon múlik, hogy hány értékkombinációra van szükség egy teszthez, és honnan származnak ezek az értékek.
| Kritérium | @Paraméterek + testng.xml | @DataProvider |
|---|---|---|
| Paraméterenkénti értékek | Pontosan egy | Korlátlan sorok |
| Adatforrás | Statikus szöveg az XML fájlban | Java kód, Excel, CSV, adatbázis, API |
| Támogatott típusok | Értékek típuskonverziója karakterláncból | Bármilyen Java tárgy |
| Teszthívások | Konfigurációnként egyszer | Adatsoronként egyszer |
| Az adatok módosítása megköveteli | Az XML fájl szerkesztése | A forráskód szerkesztése, gyakran újrafordítás nélkül |
| A legalkalmasabb | Környezeti és konfigurációs értékek, például böngésző, URL, hitelesítő adatok | Adatvezérelt tesztelés számos bemeneti kombináción |
A gyakorlatban a legtöbb csomag mindkettőt használja: az @Parameters tárolja a környezeti beállításokat, amelyek a futás során állandóak maradnak, az @DataProvider pedig a változó üzleti adatokat biztosítja. Amikor az adathalmaz kinövi a fixen kódolt tömböt, a következő lépés a beolvasása egy táblázatból.
Tesztadatok olvasása Excel fájlból a DataProvider használatával
A fixen kódolt tömbök méreteződése leáll, ha a tesztelők, akik nem írnak, Java szükséges az adatok karbantartása. A sorok táblázatba helyezése elválasztja a tesztadatokat a tesztlogikától, ami a gyakorlati formája a adatvezérelt tesztelésAz Apache POI beolvassa a munkafüzetet, és a DataProvider minden sort egyetlen teszthívássá alakít.
- Adja hozzá a függőséget. Tartalmaz
org.apache.poi:poi-ooxmla Mavenedben vagy Gradle épít. AooxmlAz artifact kezeli az .xlsx formátumot; plainpoicsak a korábbi .xls fájlokat olvassa. - Hozza létre a munkafüzetet. Helyezze a fejlécsort a 0. sorba, és soronként egy tesztesetet alatta, tesztmetódus argumentumonként egy oszloppal.
- Olvasd be a lapot egy tömbbe. Méretezd az Object[][] értékét a sorok és cellaszám alapján, hogy az új sorok kódmódosítás nélkül kerüljenek beolvasásra.
- Add vissza a szolgáltatótól. A tesztmetódus aláírása pontosan a korábbiakban marad.
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; } }
💡 Tipp: Hívás getStringCellValue() csak szövegként formázott cellákon. Egy numerikus cella dob IllegalStateException, ami a leggyakoribb hiba, ha egy táblázat azonosítókat vagy összegeket tartalmaz. Használjon egy DataFormatter minden cellatípus karakterláncként való beolvasásához, vagy kapcsolja be cell.getCellType() és explicit módon konvertál.
Az adatok kiszervezésével további száz teszteset hozzáadása táblázatszerkesztésből, nem pedig kódmódosításból áll, és ugyanaz a szolgáltató több tesztosztályt is betáplálhat a rendszeren keresztül. dataProviderClass korábban bemutatott attribútum.

















