Dostawca danych w TestNG: Selenium Przykład parametryzacji

⚡ Inteligentne podsumowanie

Parametryzacja w Selenium uruchamia tę samą metodę testową wielokrotnie na różnych zestawach danych, zmieniając jeden skrypt w obszar objęty badaniem opartym na danych. TestNG oferuje dwa mechanizmy do tego celu: adnotację @Parameters opartą na pliku testng.xml oraz adnotację @DataProvider zwracającą dwuwymiarową tablicę obiektów.

  • 🎯 Główny cel: Parametryzacja usuwa zakodowane na stałe wartości ze skryptów testowych, dzięki czemu ta sama logika weryfikuje każdą kombinację danych wejściowych, którą aplikacja musi obsługiwać.
  • 📄 Mechanizm XML: Adnotacja @Parameters odczytuje pary nazwa-wartość zadeklarowane w pliku testng.xml, co pasuje do danych wejściowych w stylu konfiguracji, w których liczba kombinacji pozostaje niewielka.
  • 🏷️ Priorytet zakresu: Parametry zadeklarowane na poziomie testu zastępują parametry o identycznych nazwach na poziomie zestawu, podczas gdy klasy spoza danego testu nadal odczytują wartość zestawu.
  • 🗂️. Mechanizm dostawcy danych: Metoda oznaczona adnotacją @DataProvider zwraca Object[][] i TestNG wywołuje test raz dla każdego wiersza, przekazując każdą kolumnę jako argument.
  • 🔗 Dostawcy zewnętrzni: Oznaczenie dostawcy jako statycznego i ustawienie dataProviderClass na @Test umożliwia kilku klasom testowym współdzielenie jednego źródła danych.
  • 🧭 Dynamiczne zestawy danych: Przyjęcie argumentu dostawcy Method lub ITestContext powoduje zwrócenie różnych danych w zależności od metody testowej lub grupy dołączonej.
  • 🛡️ Typowe awarie: Niezgodności typów pomiędzy wartościami XML i argumentami metod oraz brakujące parametry rozwiązane za pomocą @Optional są przyczyną większości błędów adnotacji.

Dostawca danych w TestNG

Tworząc oprogramowanie, zawsze zależy nam na tym, aby działało ono poprawnie z różnymi zestawami danych. Jeśli chodzi o testowanie W przypadku tego oprogramowania sprawdzenie pojedynczego zestawu danych nie wystarczy. Musimy zweryfikować, czy system akceptuje każdą kombinację, którą ma obsługiwać. W tym celu musimy sparametryzować nasze skrypty testowe. Właśnie tutaj pojawia się parametryzacja.

Parametryzacja w Selenium

Parametryzacja w Selenium to proces parametryzacji skryptów testowych w celu przekazania wielu danych do aplikacji w czasie wykonywania. Jest to strategia wykonania, która automatycznie uruchamia przypadki testowe wiele razy, używając różnych wartości. Koncepcja osiągnięta poprzez parametryzację skryptów testowych nazywa się Testowanie oparte na danych.

Rodzaj parametryzacji w TestNG

Aby ułatwić zrozumienie parametryzacji, omówimy opcje parametryzacji w jednym z najpopularniejszych frameworków Selenium WebDriver — TestNG.

Tam są dwie drogi dzięki któremu możemy osiągnąć parametryzację w TestNG:

  1. Z pomocą Adnotacja parametrów i TestNG XML plik.

Rodzaj parametryzacji w TestNG

  1. Z pomocą Dostawca danych adnotacja.

Rodzaj parametryzacji w TestNG

Rodzaj parametryzacji w TestNG

Powyższy diagram podsumowuje podział: parametry z pliku testng.xml można zadeklarować na poziomie zestawu lub testu, podczas gdy parametr z DataProvider może akceptować Method oraz ITestContext jako osobny argument. Przyjrzyjmy się im szczegółowo.

Parametry Adnotacja w TestNG

Parametry Adnotacja w TestNG to metoda służąca do przekazywania wartości do metod testowych jako argumentów za pomocą pliku .xml. Użytkownicy mogą być zobowiązani do przekazywania wartości do metod testowych w czasie wykonywania. Metoda adnotacji @Parameters może być używana w dowolnej metodzie z adnotacją @Test, @Before, @After lub @Factory.

Adnotacja parametrów za pomocą Testng.xml

Wybierz parametryzację za pomocą adnotacji, jeśli nie chcesz mieć do czynienia ze złożonością, a liczba kombinacji wejściowych jest niewielka.

Zobaczmy, jak to działa.

Scenariusz testowy

Krok 1) Uruchom przeglądarkę i przejdź do Google.com

Krok 2) Wprowadź słowo kluczowe wyszukiwania

Adnotacja parametrów za pomocą Testng.Xml

Krok 3) Sprawdź, czy wprowadzona wartość jest taka sama, jak wartość podana w naszych danych testowych

Krok 4) Powtarzaj kroki 2 i 3, aż wprowadzisz wszystkie wartości.

Autor testu Klucz wyszukiwania
Guru99 India
Krishna USA
Bhupesz Chiny

Oto przykład, jak to zrobić bez parametry:

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 Uwaga 4: Trzy wiersze w oryginalnej wersji tego przykładu nie kompilują się już lub są obecnie przestarzałe Selenium Wydania. System.setProperty("webdriver.gecko.driver", …) jest niepotrzebne od Selenium 4.6 i dalej, ponieważ Selenium Menedżer automatycznie rozwiązuje plik binarny sterownika. implicitlyWait(10, TimeUnit.SECONDS) przeciążenie zostało usunięte w Selenium 4 i zastąpiony przez implicitlyWait(Duration.ofSeconds(10)). getAttribute() został wycofany w Selenium 4.27, więc czytanie pola tekstowego używa getDomProperty("value")Każdy przykład poniżej stosuje te same trzy poprawki.

Przyjrzyj się powyższemu przykładowi i wyobraź sobie, jak skomplikowany staje się kod, gdy powtórzysz go dla trzech kombinacji danych wejściowych.

Teraz sparametryzujmy to za pomocą TestNGAby to zrobić, musisz:

  • Utwórz plik XML, w którym będą przechowywane parametry
  • W teście dodaj adnotację @Parameters

Adnotacja parametrów za pomocą Testng.Xml

Oto kompletny kod.

Poziom testowy 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>

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

Aby uruchomić skrypt, wybierz plik XML i uruchom go jako TestNG na.

Kliknij prawym przyciskiem myszy plik .xml -> Uruchom jako -> TestNG Apartament (Uwaga: Apartament)

ParametrZTestNGPlik XML.java

Parametry można definiować na dwóch poziomach:

  1. Poziom apartamentu — parametry wewnątrz <suite> tag TestNG Pliki XML zawierają parametry na poziomie pakietu.
  2. Poziom testowy — parametry wewnątrz <test> tag TestNG Pliki XML zawierają parametry na poziomie testu.

Oto ten sam test z parametrami na poziomie pakietu:

ParametrZTestNGPlik XML.java

UWAGA: Jeśli nazwa parametru jest taka sama na poziomie zestawu i testu, parametr poziomu testu ma pierwszeństwo przed parametrem poziomu zestawu. W takim przypadku wszystkie klasy na tym poziomie testu współdzielą nadpisany parametr, a klasy spoza tego poziomu testu nadal korzystają z parametru poziomu zestawu.

ParametrZTestNGPlik XML.java

Rozwiązywanie problemów

Kwestia nr 1: Wartość parametru w pliku testng.xml, której nie można rzutować na parametr odpowiadającej metody testowej, powoduje błąd.

Rozważ następujący przykład:

Rozwiązywanie problemów

Tutaj atrybut „autor” jest równy „Guru99', który jest ciągiem znaków, podczas gdy odpowiadająca mu metoda testowa oczekuje wartości całkowitej, więc zgłaszany jest wyjątek.

Kwestia nr 2: Twoje @Parameters nie mają odpowiadającej wartości w testng.xml.

Możesz rozwiązać ten problem, dodając @Opcjonalna adnotacja do odpowiedniego parametru w metodzie testowej.

Rozwiązywanie problemów

Kwestia nr 3: Chcesz przetestować wiele wartości tego samego parametru za pomocą pliku testng.xml.

Prosta odpowiedź brzmi: nie da się tego zrobić. Można mieć wiele różnych parametrów, ale każdy parametr może zawierać tylko jedną wartość. Zapobiega to zakodowaniu wartości na stałe w skrypcie i umożliwia wielokrotne wykorzystanie kodu — pomyśl o tym jak o pliku konfiguracyjnym skryptu. Jeśli potrzebujesz wielu wartości dla jednego parametru, użyj dostawcy danych.

Dostawca danych w TestNG

Dostawca danych w TestNG to metoda używana, gdy użytkownik musi przekazać złożone parametry. Złożone parametry muszą zostać utworzone z Java — obiekty złożone, obiekty z plików właściwości lub obiekty z bazy danych mogą być przekazywane przez metodę dostawcy danych. Metoda jest adnotowana @DataProvider i zwraca tablicę obiektów.

Parametry przy użyciu dostawcy danych

Adnotacja @Parameters jest prosta, ale aby przeprowadzić test na wielu zestawach danych, musimy użyć Dostawcy danych.

Aby wypełnić tysiące formularzy internetowych przy użyciu naszego środowiska testowego, potrzebujemy innej metodologii, która pozwoli na dostarczenie bardzo dużego zestawu danych w ramach jednego przebiegu wykonywania.

Koncepcję opartą na danych udało się osiągnąć dzięki @Dostawca danych adnotacja w TestNG.

Parametry przy użyciu dostawcy danych

Ma tylko jeden atrybut, 'nazwa'. Jeśli nie określisz atrybutu name, nazwa DataProvider będzie taka sama jak nazwa odpowiadającej jej metody.

Dostawca danych zwraca dwuwymiarowy Java przedmiot do metody testowej, a metoda testowa jest wywoływana M razy dla tablicy obiektów M×N. Na przykład, jeśli DataProvider zwróci tablicę 2×3 obiektów, odpowiadający jej przypadek testowy jest wywoływany 2 razy z 3 parametrami za każdym razem.

Parametry przy użyciu dostawcy danych

Kompletny przykład

Parametry przy użyciu dostawcy danych

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

Wywołaj DataProvider z innej klasy

Domyślnie DataProvider znajduje się w tej samej klasie co metoda testowa lub w jej klasie bazowej. Aby umieścić go w innej klasie, należy utworzyć metodę DataProvider. statyczny i dodaj atrybut klasa dostawcy danych do @Test adnotacja.

Wywołaj DataProvider z innej klasy

Code Przykład

Wywołaj DataProvider z innej klasy

TestClass ParametrDataproviderWithClassLevel.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" }
        };
    }
}

Typy parametrów w dostawcy danych

Metoda DataProvider obsługuje dwa typy parametrów.

Metoda wykonania — jeśli taki sam DataProvider powinien zachowywać się inaczej dla różnych metod testowych, należy użyć parametru Method.

Typy parametrów w Dataprovider

W poniższym przykładzie:

  • Sprawdzamy, czy nazwa metody to testMethodA
  • Jeśli tak, zwróć jeden zestaw wartości
  • W przeciwnym razie zwróć inny zestaw wartości
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" }
            };
        }
    }
}

Oto wynik:

Typy parametrów w Dataprovider

Kontekst testowy — można go używać do tworzenia różnych parametrów dla przypadków testowych w oparciu o grupy.

W rzeczywistości ITestContext można wykorzystać do zmieniania wartości parametrów na podstawie metod testowych, hostów lub konfiguracji testów.

Typy parametrów w Dataprovider

W poniższym przykładzie kodu:

  • Mamy 2 grupy: A i B
  • Każda metoda badawcza jest przypisana do grupy
  • Jeśli wartością grupy jest A, zwracany jest jeden zestaw danych
  • Jeśli wartością grupy jest B, zwracany jest inny zestaw danych
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;
    }
}

Uwaga: Jeśli uruchomisz TestNG Klasa jest bezpośrednio wywoływana, najpierw wywołuje dostawcę danych, a dostawca nie może odczytać informacji o grupach, ponieważ grupy nie są jeszcze dostępne. Wywołanie klasy za pośrednictwem pliku testng.xml udostępnia informacje o grupach za pośrednictwem ITestContext. Użyj poniższego kodu XML, aby uruchomić test:

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

Obydwa mechanizmy są już omówione, więc pojawia się praktyczne pytanie: który z nich wybrać?

@Parameters kontra @DataProvider: Którego użyć?

Te dwa podejścia nie są zamienne. Decyzja sprowadza się do tego, ile kombinacji wartości jest potrzebnych w teście i skąd te wartości pochodzą.

Kryterium @Parameters + testng.xml @Dostawca danych
Wartości na parametr Dokładnie jeden Nieograniczona liczba wierszy
Źródło danych Tekst statyczny w pliku XML Java kod, Excel, CSV, baza danych, API
Obsługiwane typy Wartości typu rzutowane z String Każdy Java przedmiot
Wywołania testowe Raz na konfigurację Raz na wiersz danych
Zmiana danych wymaga Edycja pliku XML Edycja kodu źródłowego, często bez ponownej kompilacji
Najlepiej nadaje się do Wartości środowiskowe i konfiguracyjne, takie jak przeglądarka, URL, referencje Testowanie oparte na danych w wielu kombinacjach danych wejściowych

W praktyce większość pakietów korzysta z obu: @Parameters przechowuje ustawienia środowiska, które pozostają niezmienne w trakcie przebiegu, a @DataProvider dostarcza zmienne dane biznesowe. Gdy zestaw danych przekroczy limit zakodowanej tablicy, kolejnym krokiem jest odczytanie go z arkusza kalkulacyjnego.

Jak odczytać dane testowe z pliku Excel za pomocą DataProvider

Zakodowane na stałe tablice przestają się skalować, gdy testerzy, którzy nie piszą Java konieczność utrzymania danych. Przeniesienie wierszy do arkusza kalkulacyjnego oddziela dane testowe od logiki testowej, co jest praktyczną formą testowanie oparte na danychApache POI odczytuje skoroszyt, a DataProvider konwertuje każdy wiersz na jedno wywołanie testu.

  1. Dodaj zależność. Zawierać org.apache.poi:poi-ooxml w Twoim Maven lub Gradle zbudować. Ten ooxml artefakt obsługuje format .xlsx; zwykły poi odczytuje tylko starsze pliki .xls.
  2. Utwórz skoroszyt. Umieść wiersz nagłówka w wierszu 0, a w każdym wierszu poniżej umieść jeden przypadek testowy, przy czym na każdy argument metody testowej umieść jedną kolumnę.
  3. Wczytaj arkusz do tablicy. Zmień rozmiar obiektu [][] na podstawie liczby wierszy i komórek, aby nowe wiersze były pobierane bez zmian w kodzie.
  4. Zwróć go od dostawcy. Podpis metody testowej pozostaje dokładnie taki sam jak poprzednio.
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;
    }
}

💡 Wskazówka: Numer Telefonu getStringCellValue() tylko w komórkach sformatowanych jako tekst. Komórka numeryczna generuje IllegalStateException, co jest najczęstszą awarią, gdy arkusz kalkulacyjny zawiera identyfikatory lub kwoty. Użyj DataFormatter aby odczytać każdy typ komórki jako ciąg lub włączyć cell.getCellType() i konwertować jawnie.

Dzięki eksternalizacji danych dodawanie setek kolejnych przypadków testowych staje się edycją arkusza kalkulacyjnego, a nie zmianą kodu, a ten sam dostawca może przekazywać wiele klas testowych przez dataProviderClass atrybut pokazany wcześniej.

FAQ

Tak. Ustawienie @DataProvider(name="x", parallel=true) Uruchamia wiersze współbieżnie. Każdy wątek potrzebuje własnej instancji WebDriver, dlatego należy przechowywać sterownik w ThreadLocal, w przeciwnym razie testy będą ze sobą kolidować.

Tak. TestNG akceptuje Iterator<Object[]>, który dostarcza wiersze leniwie, zamiast budować całą tablicę w pamięci. To rozwiązanie sprawdza się w przypadku bardzo dużych zestawów danych lub wierszy przesyłanych strumieniowo z kursora bazy danych.

Tak. AI Narzędzia generują wartości graniczne, nieprawidłowe dane wejściowe i realistyczne syntetyczne rekordy na podstawie specyfikacji pola. Revsprawdź wynik pod kątem duplikatów i potwierdź, że oczekiwane wyniki są poprawne przed dodaniem wierszy do dostawcy.

Asystenci AI sygnalizują powtarzające się wiersze danych, które korzystają z tej samej ścieżki kodu, grupują awarie według wspólnych cech wejściowych i sugerują samodzielną naprawę lokalizatory gdy zmieni się znacznik aplikacji.

Wartości w pliku testng.xml są zawsze odczytywane jako tekst. TestNG Konwertuje je na zadeklarowany typ argumentu, więc wartość nienumeryczna powiązana z argumentem int kończy się niepowodzeniem. Dopasuj wartość XML do sygnatury metody lub zaakceptuj ciąg znaków i przeanalizuj go.

Podsumuj ten post następująco: