Fornitore di dati e TestNG XML: parametrizzazione in Selenium(Esempio)

Mentre creiamo software, desideriamo sempre che funzioni diversamente con un diverso insieme di dati. Quando si tratta di Testing lo stesso software, non possiamo essere ingiusti nel testarlo con un solo set di dati. Anche in questo caso, dobbiamo verificare che il nostro sistema stia accettando tutti i set di combinazioni che dovrebbero supportare. Per questo, dobbiamo parametrizzare i nostri script di test. Ecco la parametrizzazione nella foto.

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

  1. Con l'aiuto di parametri annotazione e a TestNG XML file.

    Tipo di parametrizzazione In TestNG

  2. Con l'aiuto di DataProvider annotazione.

    Tipo di parametrizzazione In TestNG

Tipo di 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

Annotazione dei parametri con Testng.Xml

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

Annotazione dei parametri con Testng.Xml

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)

ParametroConTestNGFile XML.java

Ora i parametri possono essere definiti a 2 livelli

  1. Livello suite: i parametri all'interno del file etichetta di TestNG Il file XML sarà un parametro a livello di suite.
  2. 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

ParametroConTestNGFile XML.java

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.

ParametroConTestNGFile XML.java

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

Risoluzione dei problemi

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.

Risoluzione dei problemi

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.

Parametri utilizzando il provider di dati

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.

Parametri utilizzando il provider di dati

Esempio completo

Parametri utilizzando il provider 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.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.

Richiama DataProvider da una classe diversa

Esempio di codice

Richiama DataProvider da una classe diversa

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.

Tipi di parametri nel provider di dati

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

Tipi di parametri nel provider di dati

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.

Tipi di parametri nel provider di dati

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.