Penyedia Data di TestNG: Selenium Contoh Parameterisasi
โก Ringkasan Cerdas
Parameterisasi di Selenium Menjalankan satu metode pengujian berulang kali terhadap kumpulan data yang berbeda, mengubah satu skrip menjadi cakupan berbasis data. TestNG menawarkan dua mekanisme untuk ini: anotasi @Parameters yang didukung oleh testng.xml, dan anotasi @DataProvider yang mengembalikan array objek dua dimensi.

Saat kami membuat perangkat lunak, kami selalu menginginkan agar perangkat lunak tersebut berfungsi dengan benar dengan berbagai kumpulan data. Ketika menyangkut hal tersebut... pengujian Pada perangkat lunak tersebut, memeriksa satu set data saja tidak cukup. Kita perlu memverifikasi bahwa sistem menerima setiap kombinasi yang diharapkan untuk didukung. Untuk itu, kita perlu memparameterisasi skrip pengujian kita. Di sinilah parameterisasi berperan.
Parameterisasi di Selenium
Parameterisasi di Selenium adalah proses untuk membuat parameter skrip pengujian untuk meneruskan banyak data ke aplikasi saat runtime. Ini adalah strategi eksekusi yang secara otomatis menjalankan kasus uji beberapa kali menggunakan nilai berbeda. Konsep yang dicapai dengan membuat parameter skrip pengujian disebut Pengujian Berdasarkan Data.
Jenis Parameterisasi di TestNG
Untuk memperjelas parameterisasi, kita akan membahas opsi parameterisasi dalam salah satu framework paling populer untuk Selenium WebDriver โ TestNG.
Ada dua cara yang dengannya kita dapat mencapai parameterisasi TestNG:
- Dengan bantuan Anotasi parameter dan TestNG XML file.
- Dengan bantuan Penyedia data anotasi.
Diagram di atas merangkum pemisahan tersebut: parameter dari testng.xml dapat dideklarasikan pada level suite atau test, sedangkan parameter dari DataProvider dapat menerima Method ke ITestContext sebagai argumennya sendiri. Mari kita pelajari secara detail.
Parameter Anotasi di TestNG
Parameter Anotasi di TestNG adalah metode yang digunakan untuk meneruskan nilai ke metode pengujian sebagai argumen menggunakan file .xml. Pengguna mungkin perlu meneruskan nilai ke metode pengujian selama waktu eksekusi. Metode anotasi @Parameters dapat digunakan di metode apa pun yang memiliki anotasi @Test, @Before, @After, atau @Factory.
Anotasi parameter dengan Testng.xml
Pilih parameterisasi menggunakan anotasi ketika Anda tidak ingin berurusan dengan kompleksitas dan jumlah kombinasi inputnya kecil.
Mari kita lihat bagaimana ini bekerja.
Skenario Uji
Langkah 1) Buka browser dan kunjungi Google.com
Langkah 2) Masukkan kata kunci pencarian
Langkah 3) Pastikan nilai yang dimasukkan sama dengan nilai yang diberikan oleh data uji kami.
Langkah 4) Ulangi langkah 2 dan 3 hingga semua nilai dimasukkan.
| Penulis Tes | Kunci Pencarian |
|---|---|
| Guru99 | India |
| Krishna | Amerika Serikat |
| Bhupesh | Tiongkok |
Berikut contoh cara melakukannya tanpa parameter:
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 Catatan tahun 4: Tiga baris dalam versi asli contoh ini tidak lagi dapat dikompilasi atau sudah usang pada versi saat ini. Selenium rilis. System.setProperty("webdriver.gecko.driver", โฆ) tidak perlu dari Selenium 4.6 dan seterusnya karena Selenium Manajer secara otomatis menyelesaikan biner driver. Itu implicitlyWait(10, TimeUnit.SECONDS) kelebihan beban dihilangkan di Selenium 4 dan digantikan oleh implicitlyWait(Duration.ofSeconds(10)). getAttribute() sudah tidak digunakan lagi Selenium 4.27, jadi membaca kotak teks menggunakan getDomProperty("value")Setiap contoh di bawah ini menerapkan tiga koreksi yang sama.
Pelajari contoh di atas dan bayangkan betapa kompleksnya kode tersebut jika diulang untuk tiga kombinasi input.
Sekarang mari kita parameterisasi menggunakan TestNGUntuk melakukan hal tersebut, Anda perlu:
- Buat file XML yang akan menyimpan parameter
- Dalam pengujian, tambahkan anotasi @Parameters
Berikut kode lengkapnya.
Tingkat Tes 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>
ParameterDenganTestNGFile XML.java
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)); } }
Untuk menjalankan skrip, pilih file XML dan jalankan sebagai sebuah skrip. TestNG pada.
Klik kanan pada file .xml -> Jalankan sebagai -> TestNG Suite (Catatan: Suite)
Parameter dapat didefinisikan pada dua tingkatan:
- Tingkat suite โ parameter di dalam
<suite>label dari TestNG File XML berisi parameter tingkat suite. - Tingkat tes โ parameter di dalam
<test>label dari TestNG File XML tersebut berisi parameter tingkat pengujian.
Berikut adalah pengujian yang sama dengan parameter tingkat suite:
CATATAN: Jika nama parameter sama di tingkat suite dan tingkat pengujian, parameter tingkat pengujian akan diutamakan daripada parameter tingkat suite. Dalam hal ini, semua kelas di dalam tingkat pengujian tersebut akan menggunakan parameter yang ditimpa, dan kelas di luar tingkat pengujian tersebut akan terus menggunakan parameter tingkat suite.
Penyelesaian masalah
Masalah #1: Nilai parameter dalam testng.xml yang tidak dapat dikonversi tipenya ke parameter metode pengujian yang sesuai akan menimbulkan kesalahan.
Perhatikan contoh berikut:
Di sini, atribut 'author' sama dengan 'Guru'99', yang merupakan String, sedangkan metode pengujian yang sesuai mengharapkan nilai integer, sehingga terjadi pengecualian.
Masalah #2: Parameter @Parameters Anda tidak memiliki nilai yang sesuai di testng.xml.
Anda dapat menyelesaikan ini dengan menambahkan Anotasi @Opsional ke parameter yang sesuai dalam metode pengujian.
Masalah #3: Anda ingin menguji beberapa nilai dari parameter yang sama menggunakan testng.xml.
Jawaban sederhananya adalah ini tidak bisa dilakukan. Anda dapat memiliki beberapa parameter berbeda, tetapi setiap parameter hanya dapat menyimpan satu nilai. Ini mencegah pengkodean nilai secara langsung ke dalam skrip dan menjaga agar kode dapat digunakan kembali โ anggap saja sebagai file konfigurasi untuk skrip Anda. Jika Anda membutuhkan beberapa nilai untuk satu parameter, gunakan DataProvider sebagai gantinya.
Penyedia Data di TestNG
Penyedia Data di TestNG adalah metode yang digunakan ketika pengguna perlu mengirimkan parameter kompleks. Parameter kompleks perlu dibuat dari Java โ Objek kompleks, objek dari file properti, atau objek dari basis data dapat dilewatkan melalui metode penyedia data. Metode ini diberi anotasi @DataProvider dan mengembalikan array objek.
Parameter menggunakan Penyedia Data
Anotasi @Parameters mudah digunakan, tetapi untuk menguji dengan beberapa set data, kita perlu menggunakan Data Provider.
Untuk mengisi ribuan formulir web menggunakan kerangka kerja pengujian kami, kami membutuhkan metodologi yang berbeda yang dapat menyediakan kumpulan data yang sangat besar dalam satu alur eksekusi.
Konsep berbasis data ini dicapai dengan cara: @Penyedia data anotasi di TestNG.
Ia hanya memiliki satu atribut, 'nama'Jika Anda tidak menentukan atribut nama, nama DataProvider akan sama dengan nama metode yang sesuai.
Penyedia data mengembalikan dua dimensi Java obyek ke metode pengujian, dan metode pengujian dipanggil M kali untuk array objek MรN. Misalnya, jika DataProvider mengembalikan array objek 2ร3, kasus uji yang sesuai dipanggil 2 kali dengan 3 parameter setiap kali.
Contoh Lengkap
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" } }; } }
Panggil DataProvider dari kelas yang berbeda
Secara default, DataProvider berada di kelas yang sama dengan metode pengujian, atau di kelas dasarnya. Untuk menempatkannya di kelas lain, buat metode penyedia data tersebut statis dan tambahkan atributnya kelas Penyedia data ke @Uji anotasi.
Code Example
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)); } }
Kelas Penyedia Data.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" } }; } }
Jenis Parameter di Penyedia Data
Ada dua jenis parameter yang didukung oleh metode DataProvider.
metode โ jika sama DataProvider seharusnya berperilaku berbeda untuk metode pengujian yang berbeda, gunakan parameter Method.
Pada contoh berikut:
- Kita periksa apakah nama metodenya adalah testMethodA
- Jika ya, kembalikan satu set nilai.
- Jika tidak, kembalikan kumpulan nilai lain.
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" } }; } } }
Berikut hasilnya:
Konteks Teruji โ ini dapat digunakan untuk membuat parameter berbeda untuk kasus uji berdasarkan kelompok.
Dalam kehidupan nyata, Anda dapat menggunakan ITestContext untuk memvariasikan nilai parameter berdasarkan metode pengujian, host, atau konfigurasi pengujian.
Pada contoh kode berikut:
- Kami memiliki 2 kelompok, A dan B.
- Setiap metode pengujian ditugaskan ke grup
- Jika nilai grupnya adalah A, satu set data akan dikembalikan.
- Jika nilai grupnya adalah B, maka kumpulan data lain akan dikembalikan.
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; } }
Catatan: Jika Anda menjalankan TestNG Jika kelas dijalankan langsung, ia akan memanggil penyedia data terlebih dahulu, dan penyedia tersebut tidak dapat membaca informasi grup karena grup tersebut belum tersedia. Memanggil kelas melalui testng.xml membuat informasi grup tersedia melalui ITestContext. Gunakan XML berikut untuk menjalankan pengujian:
<!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>
Kedua mekanisme tersebut kini telah dibahas, jadi pertanyaan praktisnya adalah mana yang harus digunakan.
@Parameters vs @DataProvider: Mana yang Harus Digunakan?
Kedua pendekatan tersebut tidak dapat saling menggantikan. Keputusan bergantung pada berapa banyak kombinasi nilai yang dibutuhkan suatu pengujian dan dari mana nilai-nilai tersebut berasal.
| Kriterium | @Parameters + testng.xml | @Penyedia data |
|---|---|---|
| Nilai per parameter | Tepat satu | Baris tak terbatas |
| Sumber data | Teks statis dalam file XML | Java kode, Excel, CSV, basis data, API |
| Jenis yang didukung | Nilai yang dikonversi dari String | Apa saja Java obyek |
| Pemanggilan pengujian | Sekali per konfigurasi | Satu kali per baris data |
| Mengubah data memerlukan | Mengedit file XML | Mengedit kode sumber, seringkali tanpa kompilasi ulang. |
| Paling cocok untuk | Nilai lingkungan dan konfigurasi seperti browser, URLkredensial | Pengujian berbasis data di berbagai kombinasi input |
Dalam praktiknya, sebagian besar suite menggunakan keduanya: @Parameters membawa pengaturan lingkungan yang tetap konstan selama eksekusi, dan @DataProvider menyediakan data bisnis yang bervariasi. Ketika kumpulan data melebihi ukuran array yang telah ditentukan, langkah selanjutnya adalah membacanya dari spreadsheet.
Cara Membaca Data Uji dari File Excel Menggunakan DataProvider
Array yang dikodekan secara langsung (hardcoded) akan berhenti berkembang setelah penguji yang tidak menulis kode tersebut mulai menggunakan array yang sesuai. Java Perlu memelihara data. Memindahkan baris ke dalam spreadsheet memisahkan data pengujian dari logika pengujian, yang merupakan bentuk praktis dari pengujian berdasarkan dataApache POI membaca buku kerja, dan DataProvider mengkonversi setiap baris menjadi satu pemanggilan pengujian.
- Tambahkan dependensi tersebut. Memasukkan
org.apache.poi:poi-ooxmldi Maven Anda atau Gradle membangun. ItuooxmlArtefak menangani format .xlsx; polospoihanya membaca file .xls lama. - Buat buku kerja. Letakkan baris header di baris 0 dan satu kasus uji per baris di bawahnya, dengan satu kolom per argumen metode pengujian.
- Baca lembar kerja ke dalam sebuah array. Sesuaikan ukuran Object[][] berdasarkan jumlah baris dan sel sehingga baris baru dapat diambil tanpa perubahan kode.
- Kembalikan dari penyedia. Tanda tangan metode pengujian tetap sama seperti sebelumnya.
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; } }
๐ก Kiat: Memanggil getStringCellValue() hanya pada sel yang diformat sebagai teks. Sel numerik akan menimbulkan kesalahan. IllegalStateException, yang merupakan kegagalan paling umum ketika spreadsheet berisi ID atau jumlah. Gunakan DataFormatter untuk membaca setiap tipe sel sebagai String, atau beralih ke cell.getCellType() dan konversikan secara eksplisit.
Dengan data yang dieksternalisasi, menambahkan seratus kasus uji lagi menjadi pengeditan spreadsheet daripada perubahan kode, dan penyedia yang sama dapat memasukkan beberapa kelas uji melalui dataProviderClass atribut yang ditunjukkan sebelumnya.
















