Fornitore di dati e TestNG XML: parametrizzazione in Selenium(Esempio)
Parametrizzazione in Selenium
Parametrizzazione in Selenium è un processo per parametrizzare gli script di test al fine di passare più dati all'applicazione in fase di runtime. È una strategia di esecuzione che esegue automaticamente i casi di test più volte utilizzando valori diversi. Il concetto ottenuto parametrizzando gli script di test viene chiamato Test guidati dai dati.
Tipo di parametrizzazione in TestNG-
Per rendere la parametrizzazione più chiara, esamineremo le opzioni di parametrizzazione in uno dei framework più popolari per Selenium Driver web – TestNG.
Ci sono due strade con il quale possiamo ottenere la parametrizzazione in TestNG
I parametri di Testng.xml possono essere di livello suite o test
Il parametro di DataProvider può accettare Method e ITestContext come parametro.
Studiamoli in dettaglio –
Parametri Annotazione in TestNG
Parametri Annotazione in TestNG è un metodo utilizzato per passare valori ai metodi di test come argomenti utilizzando il file .xml. Agli utenti potrebbe essere richiesto di passare i valori ai metodi di test durante il runtime. Il metodo di annotazione @Parameters può essere utilizzato in qualsiasi metodo con annotazione @Test, @Before, @After o @Factory.
Annotazione dei parametri con Testng.xml
Selezionare la parametrizzazione mediante annotazioni quando si desidera gestire la complessità e il numero di combinazioni di input è inferiore.
Vediamo come funziona
Scenario di prova
Passaggio 1) Avvia il browser e vai su Google.com
Passaggio 2) Inserisci una parola chiave di ricerca
Passaggio 3) Verificare che il valore immesso sia uguale a quello fornito dai nostri dati di test
Passaggio 4) Ripetere 2 e 3 finché non vengono immessi tutti i valori
Autore della prova | Chiave di ricerca |
---|---|
Guru99 | India |
Krishna | USA |
Bupesh | Cina |
Ecco un esempio di come farlo SENZA parametri
package parameters; import org.testng.annotations.Test; import org.testng.AssertJUnit; import java.util.concurrent.TimeUnit; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.firefox.FirefoxDriver; public class NoParameterWithTestNGXML { String driverPath = "C:\\geckodriver.exe"; WebDriver driver; @Test public void testNoParameter() throws InterruptedException{ String author = "guru99"; String searchKey = "india"; System.setProperty("webdriver.gecko.driver", driverPath); driver= new FirefoxDriver(); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.get("https://google.com"); WebElement searchText = driver.findElement(By.name("q")); //Searching text in google text box searchText.sendKeys(searchKey); System.out.println("Welcome ->"+author+" Your search key is->"+searchKey); System.out.println("Thread will sleep now"); Thread.sleep(3000); System.out.println("Value in Google Search Box = "+searchText.getAttribute("value") +" ::: Value given by input = "+searchKey); //verifying the value in google search box AssertJUnit.assertTrue(searchText.getAttribute("value").equalsIgnoreCase(searchKey)); } }
Uno studio, l'esempio di cui sopra. Immaginate quanto complesso diventerà il codice quando faremo questo per 3 combinazioni di input
Ora parametrizziamolo utilizzando TestNG
Per fare ciò, dovrai farlo
- Creare un file XML che memorizzerà i parametri
-
Nel test, aggiungi l'annotazione @Parameters
Ecco il codice completo
Livello di prova TestNG. Xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE suite SYSTEM "http://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>
ParametroConTestNGFile XML.java
package parameters; import org.testng.AssertJUnit; import java.util.concurrent.TimeUnit; 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 { String driverPath = "C:\\geckodriver.exe"; WebDriver driver; @Test @Parameters({"author","searchKey"}) public void testParameterWithXML( @Optional("Abc") String author,String searchKey) throws InterruptedException{ System.setProperty("webdriver.gecko.driver", driverPath); driver = new FirefoxDriver(); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.get("https://google.com"); WebElement searchText = driver.findElement(By.name("q")); //Searching text in google text box searchText.sendKeys(searchKey); System.out.println("Welcome ->"+author+" Your search key is->"+searchKey); System.out.println("Thread will sleep now"); Thread.sleep(3000); System.out.println("Value in Google Search Box = "+searchText.getAttribute("value") +" ::: Value given by input = "+searchKey); //verifying the value in google search box AssertJUnit.assertTrue(searchText.getAttribute("value").equalsIgnoreCase(searchKey)); } }
Istruzioni per eseguire lo script, selezionare il file XML ed Esegui come Test NG Suite
Fare clic con il tasto destro sul file .xml -> Esegui come -> Test Suite (Nota: Suite)
Ora i parametri possono essere definiti a 2 livelli
- Livello suite: i parametri all'interno del file etichetta di TestNG Il file XML sarà un parametro a livello di suite.
- Livello di test: i parametri all'interno del file Il tag del file XML di test sarà un parametro del livello di test.
Ecco lo stesso test con parametri a livello di suite
NOTA: Nel caso in cui il nome del parametro sia lo stesso a livello di suite e a livello di test, il parametro del livello di test avrà la preferenza rispetto al livello di suite. Pertanto, in tal caso, tutte le classi all'interno di quel livello di test condivideranno il parametro sovrascritto e le altre classi che sono al di fuori del livello di test condivideranno il parametro a livello di suite.
Troubleshooting
Numero 1 # Il valore del parametro in testng.xml non può essere convertito in typecast nel parametro del metodo di test corrispondente, poiché genererà un errore.
Considera il seguente esempio
Qui, l'attributo 'author' è uguale a 'Guru99' che è una stringa e nel metodo di test corrispondente si aspetta un valore intero, quindi qui otterremo un'eccezione.
Numero 2 # I tuoi @Parameters non hanno un valore corrispondente in testing.xml.
Puoi risolvere questa situazione aggiungendo @opzionale annotazione nel parametro corrispondente nel metodo di prova.
Problema n. 3: Si desidera testare più valori dello stesso parametro utilizzando Testng.xml
La risposta semplice è che questo non può essere fatto! È possibile avere più parametri diversi, ma ogni parametro può avere un solo valore. Ciò aiuta a prevenire l'hardcoding dei valori nello script. Ciò rende il codice riutilizzabile. Consideralo come un file di configurazione per il tuo script. Se desideri utilizzare più valori per un parametro, utilizza DataProviders
Fornitore di dati in TestNG
Fornitore di dati in TestNG è un metodo utilizzato quando un utente deve passare parametri complessi. I parametri complessi devono essere creati da Java come oggetti complessi, oggetti da file di proprietà o da un database possono essere passati dal metodo del fornitore di dati. Il metodo è annotato da @DataProvider e restituisce un array di oggetti.
Parametri che utilizzano il provider di dati
L'annotazione @Parameters è semplice, ma per testare con più set di dati è necessario utilizzare Data Provider.
Per compilare migliaia di moduli web utilizzando il nostro framework di test abbiamo bisogno di una metodologia diversa che possa fornirci un set di dati molto ampio in un unico flusso di esecuzione.
Questo concetto basato sui dati è raggiunto da @DataProvider annotazione in TestNG.
Ne ha solo uno nome attributo'. Se non specifichi l'attributo name, il nome del DataProvider sarà uguale al nome del metodo corrispondente.
Restituisce il fornitore di dati un oggetto Java bidimensionale al metodo di test e al metodo di test, invocherà M volte in un tipo M*N di array di oggetti. Ad esempio, se DataProvider restituisce un array di 2*3 oggetti, il testcase corrispondente verrà richiamato 2 volte con 3 parametri ogni volta.
Esempio completo
package parameters; import java.util.concurrent.TimeUnit; 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; String driverPath = "C:\\geckodriver.exe"; @BeforeTest public void setup(){ //Create firefox driver object System.setProperty("webdriver.gecko.driver", driverPath); driver = new FirefoxDriver(); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.get("https://google.com"); } /** Test case to verify google search box * @param author * @param searchKey * @throws InterruptedException */ @Test(dataProvider="SearchProvider") public void testMethod(String author,String searchKey) throws InterruptedException{ { WebElement searchText = driver.findElement(By.name("q")); //search value in google searchbox searchText.sendKeys(searchKey); System.out.println("Welcome ->"+author+" Your search key is->"+searchKey); Thread.sleep(3000); String testValue = searchText.getAttribute("value"); System.out.println(testValue +"::::"+searchKey); searchText.clear(); //Verify if the value in google search box is correct Assert.assertTrue(testValue.equalsIgnoreCase(searchKey)); } } /** * @return Object[][] where first column contains 'author' * and second column contains 'searchKey' */ @DataProvider(name="SearchProvider") public Object[][] getDataFromDataprovider(){ return new Object[][] { { "Guru99", "India" }, { "Krishna", "UK" }, { "Bhupesh", "USA" } }; } }
Richiama DataProvider da una classe diversa
Per impostazione predefinita, DataProvider risiede nella stessa classe in cui si trova il metodo di test o la sua classe base. Per inserirlo in un'altra classe dobbiamo rendere statico il metodo del fornitore di dati e nel metodo di test dobbiamo aggiungere un attributo dataProviderClass in @Test annotazione.
Esempio di codice
TestClass ParametroDataproviderWithClassLevel.java
package parameters; import java.util.concurrent.TimeUnit; 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; String driverPath = "C:\\geckodriver.exe"; @BeforeTest public void setup(){ System.setProperty("webdriver.gecko.driver", driverPath); driver = new FirefoxDriver(); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); 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 google text box searchText.sendKeys(searchKey); System.out.println("Welcome ->"+author+" Your search key is->"+searchKey); Thread.sleep(3000); //get text from search box String testValue = searchText.getAttribute("value"); System.out.println(testValue +"::::"+searchKey); searchText.clear(); //verify if search box has 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" } }; }}
Tipi di parametri nel provider di dati
Esistono due tipi di parametri supportati dal metodo DataProvider.
Metodo- Se la STESSO DataProvider dovrebbe comportarsi diversamente con un metodo di test diverso, utilizzare il parametro Method.
Nell'esempio seguente,
- Controlliamo se il nome del metodo è testMethodA.
- Se sì, restituisci un insieme di valori
- Altrimenti restituisce un altro insieme di valori
package parameters; import java.lang.reflect.Method; import java.util.concurrent.TimeUnit; 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; String driverPath = "C:\\geckodriver.exe"; @BeforeTest public void setup(){ System.setProperty("webdriver.gecko.driver", driverPath); driver = new FirefoxDriver(); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.get("https://google.com"); } @Test(dataProvider="SearchProvider") public void testMethodA(String author,String searchKey) throws InterruptedException{ WebElement searchText = driver.findElement(By.name("q")); //Search text in search box searchText.sendKeys(searchKey); //Print author and search string System.out.println("Welcome ->"+author+" Your search key is->"+searchKey); Thread.sleep(3000); String testValue = searchText.getAttribute("value"); System.out.println(testValue +"::::"+searchKey); searchText.clear(); //Verify if google text box is showing correct value Assert.assertTrue(testValue.equalsIgnoreCase(searchKey)); } @Test(dataProvider="SearchProvider") public void testMethodB(String searchKey) throws InterruptedException{ { WebElement searchText = driver.findElement(By.name("q")); //Search text in search box searchText.sendKeys(searchKey); //Print only search string System.out.println("Welcome ->Unknown user Your search key is->"+searchKey); Thread.sleep(3000); String testValue = searchText.getAttribute("value"); System.out.println(testValue +"::::"+searchKey); searchText.clear(); //Verify if google text box is showing correct value Assert.assertTrue(testValue.equalsIgnoreCase(searchKey)); } } /** * Here DataProvider returning value on the basis of test method name * @param m * @return **/ @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" } };} } }
Ecco l'output
ITestContext– Può essere utilizzato per creare parametri diversi per casi di test basati su gruppi.
Nella vita reale, puoi utilizzare ITestContext per variare i valori dei parametri in base a metodi di test, host e configurazioni del test.
Nel seguente esempio di codice
- Abbiamo 2 gironi A e B
- Ciascun metodo di prova è assegnato a un gruppo
- Se il valore del gruppo è A, viene restituito un particolare set di dati
- Se il valore del gruppo è B, viene restituito un altro set di dati
package parameters; import java.util.concurrent.TimeUnit; 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; String driverPath = "C:\\geckodriver.exe"; @BeforeTest(groups={"A","B"}) public void setup(){ System.setProperty("webdriver.gecko.driver", driverPath); driver = new FirefoxDriver(); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.get("https://google.com"); } @Test(dataProvider="SearchProvider",groups="A") public void testMethodA(String author,String searchKey) throws InterruptedException{ { //search google textbox WebElement searchText = driver.findElement(By.name("q")); //search a value on it searchText.sendKeys(searchKey); System.out.println("Welcome ->"+author+" Your search key is->"+searchKey); Thread.sleep(3000); String testValue = searchText.getAttribute("value"); System.out.println(testValue +"::::"+searchKey); searchText.clear(); //verify correct value in searchbox Assert.assertTrue(testValue.equalsIgnoreCase(searchKey)); } } @Test(dataProvider="SearchProvider",groups="B") public void testMethodB(String searchKey) throws InterruptedException{ { //find google search box WebElement searchText = driver.findElement(By.name("q")); //search a value on it searchText.sendKeys(searchKey); System.out.println("Welcome ->Unknown user Your search key is->"+searchKey); Thread.sleep(3000); String testValue = searchText.getAttribute("value"); System.out.println(testValue +"::::"+searchKey); searchText.clear(); //verify correct value in searchbox Assert.assertTrue(testValue.equalsIgnoreCase(searchKey)); } } /** * Here the DAtaProvider will provide Object array on the basis on ITestContext * @param c * @return */ @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; } }
Nota: se esegui direttamente la tua classe testng, prima chiamerà dataprovider che non può ottenere informazioni sui gruppi poiché i gruppi non sono disponibili. Ma invece se chiami questa classe tramite testng.xml, avrà informazioni sui gruppi disponibili con ITestContext. Usa il seguente XML per chiamare il test
<!DOCTYPE suite SYSTEM "http://beust.com/testng/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>
Sommario
- Parametrizzazione è necessario creare Test guidati dai dati.
- TestNG supportare due tipi di parametrizzazione, utilizzando @Parametro+TestNG. Xml e usando@DataProvider
-
In @Parametro+TestNG. Xml i parametri possono essere posizionati a livello di suite e a livello di test. Se
Lo stesso nome del parametro è dichiarato in entrambi i posti; il parametro del livello di test avrà la preferenza rispetto al parametro del livello di tuta.
- utilizzando @Parametro+TestNG.xml è possibile impostare un solo valore alla volta, ma @DataProvider restituisce un array 2D di Object.
- Se DataProvider è presente in una classe diversa dalla classe in cui risiede il metodo di test,DataProvider dovrebbe essere metodo statico.
- Ci sono due parametri supportati da DataProvider sono Metodo e a ITestContext.