Fournisseur de données & TestNG XML : paramétrage dans Selenium(Exemple)

Lorsque nous créons un logiciel, nous souhaitons toujours qu'il fonctionne différemment avec un ensemble de données différent. Quand cela vient à Tests le même logiciel, il ne peut pas être injuste de le tester avec un seul ensemble de données. Là encore, nous devons vérifier que notre système prend en charge tous les ensembles de combinaisons censés prendre en charge. Pour cela, nous devons paramétrer nos scripts de test. Voici le paramétrage dans l'image.

Paramétrage en Selenium

Paramétrage en Selenium est un processus permettant de paramétrer les scripts de test afin de transmettre plusieurs données à l'application au moment de l'exécution. Il s'agit d'une stratégie d'exécution qui exécute automatiquement des cas de test plusieurs fois en utilisant différentes valeurs. Le concept réalisé en paramétrant les scripts de test est appelé Tests basés sur les données.

Type de paramétrage dans TestNG-

Pour rendre le paramétrage plus clair, nous passerons en revue les options de paramétrage dans l'un des frameworks les plus populaires pour Selenium Pilote Web – TestNG.

Il y a deux façons par lequel nous pouvons réaliser le paramétrage dans TestNG

  1. Avec l'aide d' Paramètres annotation et TestNG XML fichier.

    Type de paramétrage dans TestNG

  2. Avec l'aide d' Fournisseur de données annotation.

    Type de paramétrage dans TestNG

Type de paramétrage dans TestNG

Les paramètres de Testng.xml peuvent être de niveau suite ou test

Le paramètre de DataProvider peut prendre Method et ITestContext comme paramètre.

Étudions-les en détail –

Annotation des paramètres dans TestNG

Annotation des paramètres dans TestNG est une méthode utilisée pour transmettre des valeurs aux méthodes de test sous forme d'arguments à l'aide d'un fichier .xml. Les utilisateurs peuvent être amenés à transmettre les valeurs aux méthodes de test pendant l'exécution. La méthode d'annotation @Parameters peut être utilisée dans n'importe quelle méthode ayant une annotation @Test, @Before, @After ou @Factory.

Annotation des paramètres avec Testng.xml

Sélectionnez le paramétrage à l'aide d'annotations lorsque vous souhaitez gérer la complexité et que le nombre de combinaisons d'entrée est inférieur.

Voyons comment cela fonctionne

Scénario de test

Étape 1) Ouvrez votre navigateur et accédez à Google.com

Étape 2) Entrez un mot-clé de recherche

Annotation des paramètres avec Testng.Xml

Étape 3) Vérifiez que la valeur saisie est la même que celle fournie par nos données de test

Étape 4) Répétez 2 et 3 jusqu'à ce que toutes les valeurs soient saisies

Auteur du test Clé de recherche
Guru99 Inde
Krishna États-Unis
Bhupesh Chine

Voici un exemple de comment procéder SANS paramètres

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

Une étude, l'exemple ci-dessus. Imaginez à quel point le code deviendra complexe lorsque nous ferons cela pour 3 combinaisons d'entrée

Maintenant, paramétrons cela en utilisant TestNG

Pour ce faire, vous devrez

  • Créez un fichier XML qui stockera les paramètres
  • Dans le test, ajoutez l'annotation @Parameters

Annotation des paramètres avec Testng.Xml

Voici le code complet

Niveau de test 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>

ParamètreAvecTestNGFichier 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));

}
}

Instructions pour exécuter le script, sélectionner le fichier XML et exécuter en tant que Test NG Suite

Clic droit sur le fichier .xml -> Exécuter en tant que -> Tester Suite (Remarque : Suite)

ParamètreAvecTestNGFichier XML.java

Désormais, les paramètres peuvent être définis à 2 niveaux

  1. Niveau Suite – Les paramètres à l’intérieur du étiquette de TestNG Le fichier XML sera un paramètre au niveau de la suite.
  2. Niveau de test — Les paramètres à l'intérieur du La balise du fichier XML de test sera un paramètre de niveau Test.

Voici le même test avec les paramètres de niveau suite

ParamètreAvecTestNGFichier XML.java

NOTE: Si le nom du paramètre est le même au niveau de la suite et au niveau de test, le paramètre de niveau de test aura la préférence sur le niveau de la suite. Ainsi, dans ce cas, toutes les classes de ce niveau de test partageront le paramètre remplacé, et les autres classes situées en dehors du niveau de test partageront le paramètre de niveau suite.

ParamètreAvecTestNGFichier XML.java

Dépannage

Numéro 1 La valeur du paramètre dans testng.xml ne peut pas être transtypée dans le paramètre de la méthode de test correspondante, cela générera une erreur.

Considérons l'exemple suivant

Dépannage

Ici, l'attribut 'auteur' est égal à 'Guru« 99 » est une chaîne de caractères, alors que la méthode de test correspondante attend une valeur entière ; nous allons donc obtenir une exception.

Numéro 2 Vos @Parameters n’ont pas de valeur correspondante dans testing.xml.

Vous pouvez résoudre cette situation en ajoutant @optionnel annotation dans le paramètre correspondant dans la méthode de test.

Dépannage

Problème n°3 : Vous souhaitez tester plusieurs valeurs du même paramètre à l'aide de Testng.xml

La réponse simple est que cela n’est pas possible ! Vous pouvez avoir plusieurs paramètres différents, mais chaque paramètre ne peut avoir qu'une seule valeur. Cela permet d'éviter le codage en dur des valeurs dans le script. Cela rend le code réutilisable. Considérez-le comme des fichiers de configuration pour votre script. Si vous souhaitez utiliser plusieurs valeurs pour un paramètre, utilisez DataProviders

Fournisseur de données dans TestNG

Fournisseur de données dans TestNG est une méthode utilisée lorsqu'un utilisateur doit transmettre des paramètres complexes. Les paramètres complexes doivent être créés à partir de Java Des objets complexes, des objets provenant de fichiers de propriétés ou d'une base de données peuvent être transmis par la méthode du fournisseur de données. La méthode est annotée par @DataProvider et renvoie un tableau d'objets.

Paramètres utilisant Dataprovider

L'annotation @Parameters est simple, mais pour tester avec plusieurs ensembles de données, nous devons utiliser le fournisseur de données.

Pour remplir des milliers de formulaires Web à l'aide de notre cadre de test, nous avons besoin d'une méthodologie différente qui peut nous fournir un très grand ensemble de données en un seul flux d'exécution.

Ce concept axé sur les données est réalisé par @Fournisseur de données annotation dans TestNG.

Paramètres utilisant le fournisseur de données

Il n'en a qu'un Nom d'attribut'. Si vous ne spécifiez pas l'attribut name, le nom du DataProvider sera le même que le nom de la méthode correspondante.

Retours du fournisseur de données un objet JAVA bidimensionnel à la méthode de test et à la méthode de test, invoquera M fois dans un tableau d'objets de type M*N. Par exemple, si le DataProvider renvoie un tableau de 2*3 objets, le scénario de test correspondant sera invoqué 2 fois avec 3 paramètres à chaque fois.

Paramètres utilisant le fournisseur de données

Exemple complet

Paramètres utilisant le fournisseur de données

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

    }

}

Invoquer DataProvider à partir d'une classe différente

Par défaut, DataProvider réside dans la même classe que celle où se trouve la méthode de test ou sa classe de base. Pour le mettre dans une autre classe, nous devons rendre la méthode du fournisseur de données statique et dans la méthode de test, nous devons ajouter un attribut. classe de fournisseur de données in @Tester annotation.

Appeler DataProvider à partir d’une classe différente

Code Exemple

Appeler DataProvider à partir d’une classe différente

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

Types de paramètres dans le fournisseur de données

Il existe deux types de paramètres pris en charge par la méthode DataProvider.

Méthode- Si la MÊME DataProvider doit se comporter différemment avec différentes méthodes de test, utilisez le paramètre Method.

Types de paramètres dans le fournisseur de données

Dans l'exemple suivant,

  • Nous vérifions si le nom de la méthode est testMethodA.
  • Si oui, renvoie un ensemble de valeurs
  • Sinon, renvoie un autre ensemble de valeurs
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" }
            };}       
    }
}

Voici la sortie

Types de paramètres dans le fournisseur de données

ITestContext– Il peut être utilisé pour créer différents paramètres pour les cas de test basés sur des groupes.

Dans la vie réelle, vous pouvez utiliser ITestContext pour faire varier les valeurs des paramètres en fonction des méthodes de test, des hôtes et des configurations du test.

Types de paramètres dans le fournisseur de données

Dans l'exemple de code suivant

  • Nous avons 2 groupes A & B
  • Chaque méthode de test est affectée à un groupe
  • Si la valeur du groupe est A, un ensemble de données particulier est renvoyé
  • Si la valeur du groupe est B, un autre ensemble de données est renvoyé
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;		
	}
}

Remarque : Si vous exécutez directement votre classe testng, elle appellera d'abord le fournisseur de données qui ne pourra pas obtenir d'informations sur les groupes car les groupes ne sont pas disponibles. Mais au lieu de cela, si vous appelez cette classe via testng.xml, les informations sur les groupes seront disponibles avec ITestContext. Utilisez le XML suivant pour appeler le 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>

Résumé

  • Paramétrage est nécessaire de créer Tests basés sur les données.
  • TestNG prend en charge deux types de paramétrage, en utilisant @Paramètre+TestNG.xml et en utilisant@Fournisseur de données
  • In @Paramètre+TestNG.xml les paramètres peuvent être placés au niveau de la suite et au niveau de test. Si

    Le même nom de paramètre est déclaré aux deux endroits ; Le paramètre de niveau de test aura la préférence sur le paramètre de niveau de combinaison.

  • en utilisant @Paramètre+TestNG.xml, une seule valeur peut être définie à la fois, mais @DataProvider renvoie un tableau 2D d'objet.
  • Si DataProvider est présent dans la classe différente alors la classe où réside la méthode de test,Fournisseur de données devrait être méthode statique.
  • Il existe deux paramètres pris en charge par Fournisseur de données Ces Méthode et ITestContext.

Résumez cet article avec :