Proveedor de datos & TestNG XML: Parametrización en Selenium(Ejemplo)

A medida que creamos software, siempre deseamos que funcione de manera diferente con un conjunto de datos diferente. Cuando se trata de Pruebas el mismo software, no podemos ser injustos al probarlo con un solo conjunto de datos. Aquí nuevamente, debemos verificar que nuestro sistema esté tomando todo el conjunto de combinaciones que se espera que admita. Para eso, necesitamos parametrizar nuestros fragmentos de prueba. Aquí viene la parametrización en la imagen.

Parametrización en Selenium

Parametrización en Selenium es un proceso para parametrizar los scripts de prueba para pasar múltiples datos a la aplicación en tiempo de ejecución. Es una estrategia de ejecución que ejecuta automáticamente casos de prueba varias veces utilizando diferentes valores. El concepto logrado al parametrizar los scripts de prueba se llama Pruebas basadas en datos.

Tipo de Parametrización en TestNG-

Para que la parametrización sea más clara, repasaremos las opciones de parametrización en uno de los marcos más populares para Selenium controlador web – TestNG.

Hay dos maneras mediante el cual podemos lograr la parametrización en TestNG

  1. Con la ayuda de Parámetros anotación y TestNG XML .

    Tipo de parametrización en TestNG

  2. Con la ayuda de Proveedor de datos anotación.

    Tipo de parametrización en TestNG

Tipo de parametrización en TestNG

Los parámetros de Testng.xml pueden ser de nivel de suite o de prueba

El parámetro de DataProvider puede tomar Method e ITestContext como parámetro.

Estudiémoslos en detalle –

Anotación de parámetros en TestNG

Anotación de parámetros en TestNG es un método utilizado para pasar valores a los métodos de prueba como argumentos utilizando un archivo .xml. Es posible que se solicite a los usuarios que pasen los valores a los métodos de prueba durante el tiempo de ejecución. El método de anotación @Parameters se puede utilizar en cualquier método que tenga la anotación @Test, @Before, @After o @Factory.

Anotación de parámetros con Testng.xml

Seleccione la parametrización mediante anotaciones cuando desee lidiar con la complejidad y el número de combinaciones de entrada sea menor.

Veamos cómo funciona esto.

Escenario de prueba

Paso 1) Inicie el navegador y vaya a Google.com

Paso 2) Ingrese una palabra clave de búsqueda

Anotación de parámetros con Testng.Xml

Paso 3) Verifique que el valor ingresado sea el mismo que el proporcionado por nuestros datos de prueba

Paso 4) Repita 2 y 3 hasta ingresar todos los valores

Autor de la prueba Clave de búsqueda
Guru99 India
Krishna USA
Bhupesh China

Aquí un ejemplo de cómo hacerlo SIN parámetros

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

Un estudio del ejemplo anterior. Imagínese lo complejo que será el código cuando hagamos esto para tres combinaciones de entrada.

Ahora, parametricemos esto usando TestNG

Para hacerlo, necesitarás

  • Cree un archivo XML que almacenará los parámetros.
  • En la prueba, agregue la anotación @Parameters

Anotación de parámetros con Testng.Xml

Aquí está el código completo

Nivel de prueba 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>

ParámetroConTestNGArchivo 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));

}
}

Instrucciones para ejecutar el script, seleccionar el archivo XML y ejecutar como Test NG Suite

Haga clic derecho en el archivo .xml -> Ejecutar como -> Prueba Suite (Nota: Suite)

ParámetroConTestNGArchivo XML.java

Ahora, los parámetros se pueden definir en 2 niveles.

  1. Nivel de suite: los parámetros dentro del etiqueta de TestNG El archivo XML será un parámetro de nivel de suite.
  2. Nivel de prueba: los parámetros dentro de la etiqueta del archivo XML de prueba serán un parámetro de nivel de prueba.

Aquí está la misma prueba con parámetros de nivel suite.

ParámetroConTestNGArchivo XML.java

NOTA: En caso de que el nombre del parámetro sea el mismo en el nivel de suite y en el nivel de prueba, el parámetro del nivel de prueba tendrá preferencia sobre el nivel de suite. Entonces, en ese caso, todas las clases dentro de ese nivel de prueba compartirán el parámetro anulado, y otras clases que están fuera del nivel de prueba compartirán el parámetro de nivel de suite.

ParámetroConTestNGArchivo XML.java

Diagnóstico

Número 1 El valor del parámetro en testng.xml no se puede convertir al parámetro del método de prueba correspondiente, ya que generará un error.

Consideremos el siguiente ejemplo

Solución de problemas

Aquí, el atributo "autor" es igual a "Guru99", que es una cadena y en el método de prueba correspondiente se espera un valor entero, por lo que obtendremos una excepción aquí.

Número 2 Sus @Parameters no tienen un valor correspondiente en testing.xml.

Puedes resolver esta situación agregando @Opcional anotación en el parámetro correspondiente en el método de prueba.

Solución de problemas

Problema n. ° 3: Desea probar múltiples valores del mismo parámetro usando Testng.xml

¡La respuesta simple es que esto no se puede hacer! Puede tener varios parámetros diferentes, pero cada parámetro solo puede tener un valor único. Esto ayuda a evitar codificar valores en el script. Esto hace que el código sea reutilizable. Piense en ello como archivos de configuración para su secuencia de comandos. Si desea utilizar varios valores para un parámetro, utilice DataProviders

Proveedor de datos en TestNG

Proveedor de datos en TestNG es un método que se utiliza cuando un usuario necesita pasar parámetros complejos. Los parámetros complejos deben crearse a partir de Java Por ejemplo, se pueden pasar objetos complejos, objetos de archivos de propiedades o de una base de datos mediante el método del proveedor de datos. El método está anotado con @DataProvider y devuelve una matriz de objetos.

Parámetros usando el proveedor de datos

La anotación @Parameters es fácil, pero para probar con múltiples conjuntos de datos necesitamos usar el proveedor de datos.

Para completar miles de formularios web utilizando nuestro marco de prueba, necesitamos una metodología diferente que pueda brindarnos un conjunto de datos muy grande en un solo flujo de ejecución.

Este concepto basado en datos se logra mediante @Proveedor de datos anotación en TestNG.

Parámetros que utilizan el proveedor de datos

tiene solo uno Nombre del Atributo'. Si no especifica el atributo de nombre, el nombre del proveedor de datos será el mismo que el nombre del método correspondiente.

Devoluciones del proveedor de datos un objeto JAVA bidimensional al método de prueba y al método de prueba, invocará M veces en una matriz de objetos de tipo M*N. Por ejemplo, si DataProvider devuelve una matriz de 2*3 objetos, el caso de prueba correspondiente se invocará 2 veces con 3 parámetros cada vez.

Parámetros que utilizan el proveedor de datos

Ejemplo completo

Parámetros que utilizan el proveedor de datos

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

    }

}

Invocar DataProvider desde una clase diferente

De forma predeterminada, DataProvider reside en la misma clase donde está el método de prueba o su clase base. Para ponerlo en alguna otra clase necesitamos hacer que el método del proveedor de datos sea estático y en el método de prueba necesitamos agregar un atributo. clase de proveedor de datos in @Prueba anotación.

Invocar DataProvider desde una clase diferente

Ejemplo de código

Invocar DataProvider desde una clase diferente

Parámetro TestClassProviderWithClassLevel.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));
   }
}

Proveedor de datosClass.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" }
            };  
}}

Tipos de parámetros en el proveedor de datos

Hay dos tipos de parámetros admitidos por el método DataProvider.

Método- Si el MISMO DataProvider debe comportarse de manera diferente con diferentes métodos de prueba; use el parámetro Método.

Tipos de parámetros en el proveedor de datos

En el siguiente ejemplo,

  • Comprobamos si el nombre del método es testMethodA.
  • En caso afirmativo, devuelva un conjunto de valores.
  • De lo contrario, devolverá otro conjunto de valores.
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" }
            };}       
    }
}

Aquí está la salida

Tipos de parámetros en el proveedor de datos

Contexto de prueba de TI– Se puede utilizar para crear diferentes parámetros para casos de prueba basados ​​en grupos.

En la vida real, puede utilizar ITestContext para variar los valores de los parámetros según los métodos de prueba, los hosts y las configuraciones de la prueba.

Tipos de parámetros en el proveedor de datos

En el siguiente ejemplo de código

  • Tenemos 2 grupos A y B
  • Cada método de prueba se asigna a un grupo.
  • Si el valor del grupo es A, se devuelve un conjunto de datos particular
  • Si el valor del grupo es B, se devuelve otro conjunto de datos.
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: Si ejecuta directamente su clase testng, primero llamará a dataprovider, que no puede obtener información de los grupos, ya que estos no están disponibles. Pero, en cambio, si llama a esta clase a través de testng.xml, tendrá información de los grupos disponible con ITestContext. Use el siguiente XML para llamar a la clase testng.

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

Resumen

  • Parametrización es necesario crear Pruebas basadas en datos.
  • TestNG admite dos tipos de parametrización, utilizando @Parámetro+TestNG.xml y utilizando@Proveedor de datos
  • In @Parámetro+TestNG.xml Los parámetros se pueden colocar en el nivel de suite y en el nivel de prueba. Si

    El mismo nombre de parámetro se declara en ambos lugares; El parámetro de nivel de prueba tendrá preferencia sobre el parámetro de nivel de traje.

  • usando @Parámetro+TestNG.xml solo se puede establecer un valor a la vez, pero @DataProvider devuelve una matriz 2d de objeto.
  • Si DataProvider está presente en una clase diferente, entonces la clase donde reside el método de prueba,Proveedor de datos debiera ser método estático.
  • Hay dos parámetros soportados por Proveedor de datos están Método y Contexto de prueba.