Dataleverantör & TestNG XML: Parametrering i Selenium(Exempel)

När vi skapar programvara önskar vi alltid att den ska fungera annorlunda med en annan uppsättning data. När det kommer till Testning samma mjukvara, vi kan inte vara orättvist att testa den med bara en uppsättning data. Även här måste vi verifiera att vårt system tar alla kombinationer som förväntas stödja. För det måste vi parametrisera våra tester. Här kommer Parametrisering i bilden.

Parametrering in Selenium

Parametrering in Selenium är en process för att parametrisera testskripten för att skicka flera data till applikationen vid körning. Det är en exekveringsstrategi som automatiskt kör testfall flera gånger med olika värden. Konceptet som uppnås genom att parametrisera testskripten kallas Datadriven testning.

Typ av parametrering i TestNG-

För att göra parametrering tydligare kommer vi att gå igenom parametreringsalternativen i ett av de mest populära ramverken för Selenium Webdriver – TestNG.

Det finns två sätt genom vilken vi kan uppnå parametrisering i TestNG

  1. Med hjälp av parametrar anteckning och TestNG XML fil.

    Typ av parametrering In TestNG

  2. Med hjälp av DataProvider anteckning.

    Typ av parametrering In TestNG

Typ av parametrering In TestNG

Parametrar från Testng.xml kan vara svit- eller testnivå

Parameter från DataProvider kan ta Method och ITestContext som parameter.

Låt oss studera dem i detalj -

Parametrar Anteckning in TestNG

Parametrar Anteckning in TestNG är en metod som används för att skicka värden till testmetoderna som argument med .xml-fil. Användare kan behöva skicka värdena till testmetoderna under körning. @Parameters-anteckningsmetoden kan användas i alla metoder som har @Test, @Före, @After eller @Factory-anteckning.

Parametrar annotering med Testng.xml

Välj parametrering med anteckningar när du vill hantera komplexitet och antalet inmatningskombinationer är färre.

Låt se hur detta fungerar

Testscenario

Steg 1) Starta webbläsaren och gå till Google.com

Steg 2) Ange ett sökord

Parametrar Anteckning med Testng.Xml

Steg 3) Kontrollera att det inmatade värdet är detsamma som det som tillhandahålls av våra testdata

Steg 4) Upprepa 2 och 3 tills alla värden är inmatade

Testförfattare Söknyckel
Guru99 Indien
Krishna USA
Bhupesh Kina

Här är ett exempel på hur man gör UTAN parametrar

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

En studie, exemplet ovan. Föreställ dig bara hur komplex koden kommer att bli när vi gör detta för 3 ingångskombinationer

Låt oss nu parametrisera detta med hjälp av TestNG

För att göra det måste du göra det

  • Skapa en XML-fil som lagrar parametrarna
  • Lägg till kommentar @Parameters i testet

Parametrar Anteckning med Testng.Xml

Här är den fullständiga koden

Testnivå 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>

ParameterMedTestNGXML.java-fil

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

}
}

Instruktioner för att köra skriptet, välj XML-filen och Kör som Test NG Suite

Högerklicka på .xml-fil -> Kör som -> Testng Svit (Obs! Svit)

ParameterMedTestNGXML.java-fil

Nu kan parametrar definieras på 2 nivåer

  1. Svitnivå – Parametrarna inuti tagg av TestNG XML-fil kommer att vara en parameter på svitnivå.
  2. Testnivå — Parametrarna inuti taggen för att testa XML-filen kommer att vara en testnivåparameter.

Här är samma test med parametrar på suitenivå

ParameterMedTestNGXML.java-fil

OBS: Om parameternamnet är samma i svitnivå och testnivå kommer testnivåparametern att prioriteras framför svitnivå. Så, i så fall kommer alla klasser inom den testnivån att dela den åsidosatta parametern, och andra klasser som ligger utanför testnivån kommer att dela parametern på svitnivån.

ParameterMedTestNGXML.java-fil

Felsökning

Utgåva # 1 Parametervärdet i testng.xml kan inte typcastas till motsvarande testmetods parameter det kommer att ge ett fel.

Betrakta följande exempel

Felsökning

Här är 'author'-attributet lika med 'Guru99' som är en sträng och i motsvarande testmetod förväntar det sig ett heltalsvärde, så vi får ett undantag här.

Utgåva # 2 Dina @parametrar har inte ett motsvarande värde i testing.xml.

Du kan lösa denna situation genom att lägga till @frivillig anteckning i motsvarande parameter i testmetoden.

Felsökning

Problem nr 3: Du vill testa flera värden för samma parameter med Testng.xml

Det enkla svaret är att detta inte kan göras! Du kan ha flera olika parametrar, men varje parameter kan bara ha ett enda värde. Detta hjälper till att förhindra hårdkodning av värden i skriptet. Detta gör koden återanvändbar. Se det som konfigurationsfiler för ditt skript. Om du vill använda flera värden för en parameter använd DataProviders

Dataleverantör i TestNG

Dataleverantör i TestNG är en metod som används när en användare behöver skicka komplexa parametrar. Komplexa parametrar måste skapas från Java såsom komplexa objekt, objekt från egenskapsfiler eller från en databas kan skickas med dataleverantörsmetoden. Metoden är kommenterad av @DataProvider och den returnerar en array av objekt.

Parametrar med hjälp av Dataprovider

@Parameters annotering är lätt men för att testa med flera uppsättningar data måste vi använda Data Provider.

För att fylla tusentals webbformulär med hjälp av vårt testramverk behöver vi en annan metod som kan ge oss en mycket stor datauppsättning i ett enda exekveringsflöde.

Detta datadrivna koncept uppnås av @Dataleverantör anteckning i TestNG.

Parametrar som använder Dataprovider

Den har bara en attribut 'namn'. Om du inte anger namnattributet kommer DataProviders namn att vara detsamma som motsvarande metodnamn.

Dataleverantören återkommer ett tvådimensionellt JAVA-objekt till testmetoden och testmetoden, kommer att anropa M gånger i en M*N-typ av objektmatris. Till exempel, om DataProvider returnerar en array med 2*3 objekt, kommer motsvarande testfall att anropas 2 gånger med 3 parametrar varje gång.

Parametrar som använder Dataprovider

Komplett exempel

Parametrar som använder Dataprovider

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

    }

}

Anropa DataProvider från en annan klass

Som standard finns DataProvider i samma klass där testmetoden är eller dess basklass. För att lägga det i någon annan klass måste vi göra dataleverantörsmetoden som statisk och i testmetoden måste vi lägga till ett attribut dataProviderClass in @Testa anteckning.

Anropa DataProvider från annan klass

Kodsexempel

Anropa DataProvider från annan klass

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

Typer av parametrar i Dataprovider

Det finns två typer av parametrar som stöds av DataProvider-metoden.

Metod- Om SAMMA DataProvider bör bete sig annorlunda med olika testmetoder, använd metodparametern.

Typer av parametrar i Dataprovider

I följande exempel,

  • Vi kontrollerar om metodnamnet är testMethodA.
  • Om ja returnera en uppsättning värde
  • Annars returnerar en annan uppsättning värde
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" }
            };}       
    }
}

Här är utgången

Typer av parametrar i Dataprovider

ITestContext– Det kan användas för att skapa olika parametrar för testfall baserat på grupper.

I verkligheten kan du använda ITestContext för att variera parametervärden baserat på testmetoder, värdar, testkonfigurationer.

Typer av parametrar i Dataprovider

I följande kodexempel

  • Vi har 2 grupper A & B
  • Varje testmetod tilldelas en grupp
  • Om värdet på gruppen är A, returneras en viss datamängd
  • Om värdet på gruppen är B, returneras en annan datamängd
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;		
	}
}

Obs: Om du kör din testklass direkt, kommer den först att anropa dataleverantören som inte kan få gruppinformation eftersom grupper inte är tillgängliga. Men istället om du anropar den här klassen via testng.xml, kommer den att ha gruppinformation tillgänglig med ITestContext. Använd följande XML för att anropa testet

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

Sammanfattning

  • Parametrisering krävs för att skapa Datadriven testning.
  • TestNG stödja två typer av parametrering, med hjälp av @Parameter+TestNG. Xml och använda@Dataleverantör
  • In @Parameter+TestNG. Xml parametrar kan placeras i svitnivå och testnivå. Om

    Samma parameternamn deklareras på båda ställena; testnivåparameter kommer att få företräde framför färgnivåparameter.

  • med @Parameter+TestNG.xml kan endast ett värde ställas in åt gången, men @DataProvider returnerar en 2d-array av objekt.
  • Om DataProvider finns i den andra klassen då klassen där testmetoden finns,DataProvider bör vara statisk metod.
  • Det finns två parametrar som stöds av DataProvider är Metod och ITestContext.