DataProvider in TestNG: Selenium Parameteriseringsvoorbeeld

⚡ Slimme samenvatting

Parametrering in Selenium Voert één testmethode herhaaldelijk uit op verschillende datasets, waardoor één script datagestuurde dekking mogelijk maakt. TestNG biedt hiervoor twee mechanismen: de @Parameters-annotatie, ondersteund door testng.xml, en de @DataProvider-annotatie, die een tweedimensionale objectarray retourneert.

  • 🎯 Kerndoel: Parameterisering verwijdert vastgelegde waarden uit testscripts, zodat dezelfde logica elke invoercombinatie valideert die de applicatie moet ondersteunen.
  • 📄 XML-mechanisme: De @Parameters-annotatie leest naam-waardeparen die zijn gedeclareerd in testng.xml, wat geschikt is voor configuratie-achtige invoer waarbij het aantal combinaties klein blijft.
  • ???? ️ Prioriteit van het toepassingsgebied: Parameters die op testniveau worden gedeclareerd, overschrijven identieke parameters op suite-niveau, terwijl klassen buiten die test de suite-waarde blijven gebruiken.
  • 🗂️ Mechanisme voor gegevensverstrekkers: Een methode met de annotatie @DataProvider retourneert Object[][], en TestNG Roept de test eenmaal per rij aan, waarbij elke kolom als argument wordt doorgegeven.
  • 🔗 Externe leveranciers: Door de provider als statisch te markeren en dataProviderClass in te stellen op @Test kunnen meerdere testklassen één gegevensbron delen.
  • 🧭 Dynamische datasets: Het accepteren van Method of ITestContext als providerargument retourneert verschillende gegevens per testmethode of per opgenomen groep.
  • 🛡️ Veelvoorkomende fouten: Typefouten tussen XML-waarden en methodeargumenten, en ontbrekende parameters die met @Optional worden opgelost, veroorzaken de meeste annotatiefouten.

DataProvider in TestNG

Bij het ontwikkelen van software willen we altijd dat deze correct werkt met verschillende datasets. Als het gaat om... het testen van Voor die software is het controleren van één enkele dataset niet voldoende. We moeten verifiëren dat het systeem elke combinatie accepteert die het zou moeten ondersteunen. Daarvoor moeten we onze testscripts parameteriseren. Dit is waar parameterisering om de hoek komt kijken.

Parametrering in Selenium

Parametrering in Selenium is een proces om de testscripts te parametriseren om tijdens runtime meerdere gegevens door te geven aan de applicatie. Het is een uitvoeringsstrategie waarbij testgevallen automatisch meerdere keren worden uitgevoerd met verschillende waarden. Het concept dat wordt bereikt door het parametriseren van de testscripts wordt genoemd Datagedreven testen.

Type parametrering in TestNG

Om parameterisering te verduidelijken, zullen we de parameteriseringsopties in een van de populairste frameworks voor Selenium WebDriver — TestNG.

Er zijn twee manieren waarmee we parametrisering kunnen bereiken TestNG:

  1. Met behulp van de Parameterannotatie en TestNG XML bestand.

Type parametrering In TestNG

  1. Met behulp van de Data provider annotatie.

Type parametrering In TestNG

Type parametrering In TestNG

Het bovenstaande diagram vat de splitsing samen: parameters uit testng.xml kunnen worden gedeclareerd op suite- of testniveau, terwijl een parameter van een DataProvider kan accepteren... Method en ITestContext als eigen argument. Laten we ze eens nader bekijken.

Parameters Annotatie in TestNG

Parameters Annotatie in TestNG Dit is een methode om waarden als argumenten door te geven aan testmethoden via een XML-bestand. Gebruikers moeten de waarden mogelijk tijdens de uitvoering aan de testmethoden doorgeven. De annotatiemethode `@Parameters` kan worden gebruikt in elke methode met de annotaties `@Test`, `@Before`, `@After` of `@Factory`.

Parameterannotatie met Testng.xml

Kies voor parameterisering met behulp van annotaties als u geen complexe situaties wilt meemaken en het aantal invoercombinaties klein is.

Laten we eens kijken hoe dit werkt.

Testscenario

Stap 1) Start de browser en ga naar Google.com

Stap 2) Voer een zoekwoord in

Parameterannotatie met Testng.Xml

Stap 3) Controleer of de ingevoerde waarde overeenkomt met de waarde in onze testgegevens.

Stap 4) Herhaal stap 2 en 3 totdat alle waarden zijn ingevoerd.

Auteur testen Zoeksleutel
Guru99 India
Krishna USA
Bhupesh China

Hier volgt een voorbeeld van hoe je dat kunt doen. zonder parameters:

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 Opmerking voor 4: Drie regels in de oorspronkelijke versie van dit voorbeeld compileren niet meer of zijn verouderd in de huidige versie. Selenium releases. System.setProperty("webdriver.gecko.driver", …) is niet nodig vanaf Selenium 4.6 en verder omdat Selenium De manager lost het binaire stuurprogramma automatisch op. implicitlyWait(10, TimeUnit.SECONDS) overbelasting werd verwijderd in Selenium 4 en vervangen door implicitlyWait(Duration.ofSeconds(10)). getAttribute() werd afgekeurd in Selenium 4.27, dus het lezen van een tekstvak maakt gebruik van getDomProperty("value")Elk voorbeeld hieronder past dezelfde drie correcties toe.

Bestudeer het bovenstaande voorbeeld en bedenk hoe complex de code wordt als dit wordt herhaald voor drie verschillende invoercombinaties.

Laten we het nu parameteriseren met behulp van TestNGOm dat te doen, moet je het volgende doen:

  • Maak een XML-bestand waarin de parameters worden opgeslagen
  • Voeg in de test de annotatie @Parameters toe.

Parameterannotatie met Testng.Xml

Hier is de volledige code.

Test niveau 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>

ParameterMetTestNGXML.java-bestand

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));
    }
}

Om het script uit te voeren, selecteer je het XML-bestand en voer je het uit als een TestNG op.

Klik met de rechtermuisknop op het .xml-bestand -> Uitvoeren als -> TestNG Suite (Opmerking: Suite)

ParameterMetTestNGXML.java-bestand

Parameters kunnen op twee niveaus worden gedefinieerd:

  1. Suiteniveau — de parameters binnen de <suite> tag van de TestNG XML-bestanden bevatten parameters op suite-niveau.
  2. Test niveau — de parameters binnen de <test> tag van de TestNG XML-bestanden bevatten parameters op testniveau.

Hier is dezelfde test met parameters op suite-niveau:

ParameterMetTestNGXML.java-bestand

NOTITIE: Als de parameternaam op suite-niveau en testniveau hetzelfde is, heeft de parameter op testniveau voorrang boven die op suite-niveau. In dat geval delen alle klassen binnen dat testniveau de overschreven parameter, terwijl klassen buiten dat testniveau de parameter op suite-niveau blijven gebruiken.

ParameterMetTestNGXML.java-bestand

Problemen oplossen

Probleem nr. 1: Een parameterwaarde in testng.xml die niet kan worden omgezet naar het overeenkomstige type van de parameter van de testmethode, veroorzaakt een fout.

Overweeg het volgende voorbeeld:

Probleemoplossen

Hier is het attribuut 'author' gelijk aan 'Guru'99', wat een tekenreeks is, terwijl de bijbehorende testmethode een geheel getal verwacht, waardoor een uitzondering wordt gegenereerd.

Probleem nr. 2: Uw @Parameters hebben geen overeenkomstige waarde in testng.xml.

Je kunt dit oplossen door toe te voegen: @Optionele annotatie naar de overeenkomstige parameter in de testmethode.

Probleemoplossen

Probleem nr. 3: Je wilt meerdere waarden van dezelfde parameter testen met behulp van testng.xml.

Het simpele antwoord is dat dit niet mogelijk is. Je kunt wel meerdere verschillende parameters hebben, maar elke parameter kan slechts één waarde bevatten. Dit voorkomt dat waarden in het script worden vastgelegd en zorgt ervoor dat de code herbruikbaar blijft – zie het als een configuratiebestand voor je script. Als je meerdere waarden voor één parameter nodig hebt, gebruik dan een DataProvider.

Gegevensprovider in TestNG

Gegevensprovider in TestNG Dit is een methode die wordt gebruikt wanneer een gebruiker complexe parameters moet doorgeven. Complexe parameters moeten worden aangemaakt vanuit Java — Complexe objecten, objecten uit eigenschappenbestanden of objecten uit een database kunnen worden doorgegeven via de data provider-methode. De methode is geannoteerd met @DataProvider en retourneert een array van objecten.

Parameters met behulp van Dataprovider

De @Parameters-annotatie is eenvoudig, maar om met meerdere datasets te testen, moeten we een Data Provider gebruiken.

Om duizenden webformulieren in te vullen met ons testframework, hebben we een andere methodologie nodig die een zeer grote dataset in één enkele uitvoeringsworkflow kan verwerken.

Dit datagestuurde concept wordt gerealiseerd door de @Data provider annotatie in TestNG.

Parameters met behulp van Dataprovider

Er is er maar één attribuut, 'naam'Als u het naamkenmerk niet opgeeft, is de naam van de DataProvider gelijk aan de naam van de corresponderende methode.

Een gegevensaanbieder retourneert een tweedimensionale Java object naar de testmethode, en de testmethode wordt M keer aangeroepen voor een array van M×N objecten. Als de DataProvider bijvoorbeeld een array van 2×3 objecten retourneert, wordt de bijbehorende testcase 2 keer aangeroepen met telkens 3 parameters.

Parameters met behulp van Dataprovider

Compleet voorbeeld

Parameters met behulp van Dataprovider

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" }
        };
    }
}

Roep DataProvider aan vanuit een andere klasse

Standaard bevindt een DataProvider zich in dezelfde klasse als de testmethode, of in de basisklasse ervan. Om deze in een andere klasse te plaatsen, moet u de DataProvider-methode aanpassen. statisch en voeg het attribuut toe dataProviderClass aan de @Toets annotatie.

Roep DataProvider aan vanuit een andere klasse

Code Voorbeeld

Roep DataProvider aan vanuit een andere klasse

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" }
        };
    }
}

Soorten parameters in Dataprovider

De DataProvider-methode ondersteunt twee soorten parameters.

Methode — als de dezelfde De DataProvider moet zich anders gedragen voor verschillende testmethoden; gebruik hiervoor de parameter Method.

Soorten parameters in Dataprovider

In het volgende voorbeeld:

  • We controleren of de methodenaam testMethodA is.
  • Indien ja, retourneer één set waarden.
  • Anders moet een andere set waarden worden geretourneerd.
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" }
            };
        }
    }
}

Dit is de uitvoer:

Soorten parameters in Dataprovider

ITestContext — Dit kan worden gebruikt om verschillende parameters voor testgevallen te creëren op basis van groepen.

In de praktijk kun je ITestContext gebruiken om parameterwaarden te variëren op basis van testmethoden, hosts of testconfiguraties.

Soorten parameters in Dataprovider

In het volgende codevoorbeeld:

  • We hebben 2 groepen, A en B.
  • Elke testmethode wordt toegewezen aan een groep
  • Als de groepswaarde A is, wordt één dataset geretourneerd.
  • Als de groepswaarde B is, wordt een andere dataset geretourneerd.
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;
    }
}

Let op: Als je de TestNG Als de klasse rechtstreeks wordt aangeroepen, wordt eerst de data provider aangeroepen. De provider kan de groepsgegevens echter niet lezen omdat de groepen nog niet beschikbaar zijn. Door de klasse via testng.xml aan te roepen, worden de groepsgegevens beschikbaar via ITestContext. Gebruik de volgende XML om de test uit te voeren:

<!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>

Beide mechanismen zijn nu behandeld, dus de praktische vraag is welke je moet kiezen.

@Parameters versus @DataProvider: welke te gebruiken?

De twee benaderingen zijn niet uitwisselbaar. De keuze hangt af van hoeveel waardecombinaties een test nodig heeft en waar die waarden vandaan komen.

Criterium @Parameters + testng.xml @Data provider
Waarden per parameter Precies één Onbeperkt aantal rijen
Databron Statische tekst in het XML-bestand Java code, Excel, CSV, database, API
Ondersteunde typen Waarden gecast van String naar String Elke Java object
Testoproepen Eenmaal per configuratie Eenmaal per gegevensrij
Het wijzigen van gegevens vereist Het XML-bestand bewerken Het bewerken van de broncode, vaak zonder hercompilatie.
Het meest geschikt voor: Omgevings- en configuratiewaarden zoals browser, URL, referenties Datagestuurd testen met veel verschillende inputcombinaties

In de praktijk gebruiken de meeste softwarepakketten beide: @Parameters bevat de omgevingsinstellingen die constant blijven tijdens een run, en @DataProvider levert de wisselende bedrijfsgegevens. Wanneer de dataset te groot wordt voor een vastgelegde array, is de volgende stap het inlezen ervan uit een spreadsheet.

Hoe lees je testgegevens uit een Excel-bestand met behulp van DataProvider?

Hardcoded arrays schalen niet meer zodra testers die niet schrijven Java De gegevens moeten behouden blijven. Door de rijen naar een spreadsheet te verplaatsen, worden testgegevens gescheiden van testlogica, wat de praktische vorm is van datagedreven testenApache POI leest het werkblad en de DataProvider zet elke rij om in een testaanroep.

  1. Voeg de afhankelijkheid toe. omvatten org.apache.poi:poi-ooxml in uw Maven of Gradle bouw. ​​De ooxml artifact verwerkt het .xlsx-formaat; plain poi Kan alleen oudere .xls-bestanden lezen.
  2. Maak het werkboek aan. Plaats de kopregel op rij 0 en daaronder één testgeval per rij, met één kolom per argument van de testmethode.
  3. Lees de gegevens in een array. Bepaal de grootte van het Object[][] op basis van het aantal rijen en cellen, zodat nieuwe rijen worden opgepakt zonder dat de code hoeft te worden aangepast.
  4. Stuur het terug naar de leverancier. De methodehandtekening van de test blijft exact hetzelfde als voorheen.
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;
    }
}

💡Tip: Bel getStringCellValue() Alleen bij cellen die als tekst zijn opgemaakt. Een numerieke cel geeft een foutmelding. IllegalStateExceptionDit is de meest voorkomende fout wanneer een spreadsheet ID's of bedragen bevat. Gebruik een DataFormatter om elk celtype als een tekenreeks te lezen, of om dit in te schakelen cell.getCellType() en expliciet converteren.

Doordat de data extern beschikbaar is, wordt het toevoegen van honderd extra testgevallen een kwestie van een spreadsheetbewerking in plaats van een codewijziging, en dezelfde provider kan meerdere testklassen door de data heen sturen. dataProviderClass eerder getoonde eigenschap.

Veelgestelde vragen

Ja. Instelling @DataProvider(name="x", parallel=true) De rijen worden gelijktijdig verwerkt. Elke thread heeft zijn eigen WebDriver-instantie nodig, dus sla de driver op in een ThreadLocal, anders interfereren de tests met elkaar.

Ja. TestNG accepteert Iterator<Object[]>Deze methode levert rijen pas aan wanneer ze nodig zijn, in plaats van de hele array in het geheugen op te bouwen. Dit is geschikt voor zeer grote datasets of rijen die via een databasecursor worden aangeleverd.

Ja. AI De tools genereren grenswaarden, ongeldige invoer en realistische synthetische gegevens op basis van een veldspecificatie. RevControleer de uitvoer op duplicaten en bevestig dat de verwachte resultaten correct zijn voordat u rijen aan de provider toevoegt.

AI-assistenten signaleren redundante gegevensrijen die hetzelfde codepad volgen, clusteren fouten op basis van gedeelde invoerkenmerken en suggereren zelfherstel. zoekertjes wanneer de applicatiemarkup verandert.

Waarden in testng.xml worden altijd als tekst gelezen. TestNG Converteert ze naar het gedeclareerde argumenttype, waardoor een niet-numerieke waarde die aan een int-argument is gekoppeld, mislukt. Vergelijk de XML-waarde met de methodehandtekening, of accepteer een String en parseer deze.

Vat dit bericht samen met: