Data provider & TestNG XML: Parametrering in Selenium(Voorbeeld)

Terwijl we software maken, willen we altijd dat deze anders zou werken met een andere set gegevens. Als het aankomt op Testen hetzelfde stukje software is, kunnen we niet oneerlijk zijn als we het met slechts één set gegevens testen. Ook hier moeten we verifiëren dat ons systeem alle combinaties gebruikt die naar verwachting zullen ondersteunen. Daarvoor moeten we onze testscripts parametriseren. Hier komt de parameterisering in beeld.

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 parametrisatie duidelijker te maken, zullen we de parametrisatie-opties doornemen in een van de meest populaire raamwerken Selenium Webdriver – TestNG.

Er zijn twee manieren waarmee we parametrisering kunnen bereiken TestNG

  1. Dankzij parameters aantekening en TestNG XML bestand.

    Type parametrering In TestNG

  2. Dankzij Data provider annotatie.

    Type parametrering In TestNG

Type parametrering In TestNG

Parameters van Testng.xml kunnen suite- of testniveau zijn

Parameter van DataProvider kan Method en ITestContext als parameter gebruiken.

Laten we ze in detail bestuderen –

Parameters Annotatie in TestNG

Parameters Annotatie in TestNG is een methode die wordt gebruikt om waarden door te geven aan de testmethoden als argumenten met behulp van een .xml-bestand. Mogelijk wordt van gebruikers gevraagd de waarden tijdens de uitvoering aan de testmethoden door te geven. De annotatiemethode @Parameters kan worden gebruikt in elke methode met de annotatie @Test, @Before, @After of @Factory.

Parameterannotatie met Testng.xml

Selecteer parameterisering met behulp van annotaties wanneer u met complexiteit te maken wilt krijgen en het aantal invoercombinaties beperkt 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 dezelfde is als die uit onze testgegevens

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

Auteur testen Zoeksleutel
Guru99 India
Krishna USA
Bhupesh China

Hier is een voorbeeld van hoe u dit kunt doen ZONDER parameters

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

Een studie, het bovenstaande voorbeeld. Stel je eens voor hoe complex de code wordt als we dit doen voor 3 invoercombinaties

Laten we dit nu parametriseren met behulp van TestNG

Om dit te doen, zul je dit moeten 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 "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>

ParameterMetTestNGXML.java-bestand

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

}
}

Instructies om het script uit te voeren, selecteer het XML-bestand en Uitvoeren als Test NG Suite

Klik met de rechtermuisknop op het XML-bestand -> Uitvoeren als -> Testen Suite (Opmerking: Suite)

ParameterMetTestNGXML.java-bestand

Nu kunnen parameters op 2 niveaus worden gedefinieerd

  1. Suiteniveau – De parameters binnen het label van TestNG XML-bestand zal een parameter op suiteniveau zijn.
  2. Testniveau — De parameters binnen het tag van het testen van het XML-bestand zal een testniveauparameter zijn.

Hier is dezelfde test met parameters op suiteniveau

ParameterMetTestNGXML.java-bestand

NOTITIE: Als de parameternaam hetzelfde is op suiteniveau en op testniveau, krijgt de testniveauparameter voorrang op suiteniveau. Dus in dat geval zullen alle klassen binnen dat testniveau de overschreven parameter delen, en zullen andere klassen die zich buiten het testniveau bevinden de parameter op suiteniveau delen.

ParameterMetTestNGXML.java-bestand

Troubleshooting

Nummer # 1 De parameterwaarde in testng.xml kan niet worden omgezet naar de parameter van de overeenkomstige testmethode. Dit zal een fout opleveren.

Beschouw het volgende voorbeeld

Probleemoplossen

Hier is het attribuut 'auteur' gelijk aan 'Guru99', wat een string is en in de corresponderende testmethode wordt een geheel getal verwacht, dus we krijgen hier een uitzondering.

Nummer # 2 Uw @Parameters hebben geen overeenkomstige waarde in testen.xml.

U kunt deze situatie oplossen door toe te voegen @optioneel aantekening in de overeenkomstige parameter in de testmethode.

Probleemoplossen

Probleem nr. 3: U wilt meerdere waarden van dezelfde parameter testen met behulp van Testng.xml

Het simpele antwoord is: dit kan niet! U kunt meerdere verschillende parameters hebben, maar elke parameter kan slechts één waarde hebben. Dit helpt bij het voorkomen van hardcoding-waarden in het script. Dit maakt code herbruikbaar. Zie het als configuratiebestanden voor uw script. Als u meerdere waarden voor een parameter wilt gebruiken, gebruikt u DataProviders

Gegevensprovider in TestNG

Gegevensprovider in TestNG is een methode die wordt gebruikt wanneer een gebruiker complexe parameters moet doorgeven. Complexe parameters moeten worden gemaakt van Java zoals complexe objecten, objecten uit property files of uit een database kunnen worden doorgegeven door de data provider methode. De methode is geannoteerd door @DataProvider en retourneert een array van objecten.

Parameters met behulp van Dataprovider

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

Om duizenden webformulieren te kunnen invullen met ons testframework hebben we een andere methodologie nodig die ons in één enkele uitvoeringsstroom een ​​zeer grote dataset kan opleveren.

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

Parameters met behulp van Dataprovider

Er is er maar één attribuut naam'. Als u het name-attribuut niet opgeeft, zal de naam van de DataProvider hetzelfde zijn als de corresponderende methodenaam.

Gegevensprovider retourneert een tweedimensionaal JAVA-object aan de testmethode en de testmethode, zal M keer aanroepen in een objectarray van het M*N-type. 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.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" }
        };

    }

}

Roep DataProvider aan vanuit een andere klasse

Standaard bevindt DataProvider zich in dezelfde klasse als de testmethode of in de basisklasse ervan. Om het in een andere klasse te plaatsen, moeten we de dataprovidermethode statisch maken en in de testmethode moeten we een attribuut toevoegen dataProviderClass in @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.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" }
            };  
}}

Soorten parameters in Dataprovider

Er worden twee soorten parameters ondersteund door de DataProvider-methode.

Methode- Als de DEZELFDE DataProvider zou zich anders moeten gedragen met verschillende testmethoden, gebruik de Method-parameter.

Soorten parameters in Dataprovider

In het volgende voorbeeld,

  • We controleren of de naam van de methode testMethodA is.
  • Zo ja, retourneer één set waarden
  • Anders retourneert u nog een set waarden
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" }
            };}       
    }
}

Hier is de uitvoer

Soorten parameters in Dataprovider

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

In het echte leven kunt u ITestContext gebruiken om parameterwaarden te variëren op basis van testmethoden, hosts en configuraties van de test.

Soorten parameters in Dataprovider

In het volgende codevoorbeeld

  • We hebben 2 groepen A en B
  • Elke testmethode wordt toegewezen aan een groep
  • Als de waarde van de groep A is, wordt een bepaalde gegevensset geretourneerd
  • Als de waarde van de groep B is, wordt een andere gegevensset geretourneerd
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;		
	}
}

Opmerking: Als u uw testng-klasse rechtstreeks uitvoert, zal deze eerst dataprovider aanroepen die geen groepsinformatie kan ophalen omdat groepen niet beschikbaar zijn. Maar als u deze klasse aanroept via testng.xml, zal deze groepsinformatie beschikbaar hebben met ITestContext. Gebruik de volgende XML om de test aan te roepen

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

Samenvatting

  • parametrering is nodig om te creëren Datagedreven testen.
  • TestNG ondersteunen twee soorten parametrisering, met behulp van @Parameter+TestNG. Xml en gebruiken@Data provider
  • In @Parameter+TestNG. Xml parameters kunnen op suiteniveau en testniveau worden geplaatst. Als

    Op beide plaatsen wordt dezelfde parameternaam gedeclareerd; De parameter op testniveau krijgt de voorkeur boven de parameter op pakniveau.

  • met behulp van @Parameter+TestNG.xml Er kan slechts één waarde tegelijk worden ingesteld, maar @DataProvider retourneert een 2D-array van objecten.
  • Als DataProvider aanwezig is in de andere klasse, dan is de klasse waar de testmethode zich bevindt,Data provider moet statische methode.
  • Er worden twee parameters ondersteund door Data provider zijn Methode en ITestContext.