¿Qué es testNG y cómo lo puedo utilizar?

walle

Hace unos días escribí un post sobre cómo empezar a trabajar con testing automatizado, de forma sencilla, pensado para empezar desde cero. En ese post, utilizamos un proyecto maven con selenium webdriver para poder escribir un test muy básico, pero no integramos ninguna otra herramienta para poder tener más control y seguir mejores prácticas de desarrollo.

Hoy me gustaría hablar de testng, una herramienta inspirada en jUnit y nUnit, pero que agrega algunas funcionalidades interesantes para controlar nuestras pruebas. Cabe destacar que testng no es exclusivo de Selenium, de hecho entre sí no tienen nada que ver, aunque se usen mucho juntos, sino que lo podemos utilizar para pruebas unitarias con java, para appium o cualquier otro framework basado en java.

Si te interesa aprender, te invito a unirte al grupo Testing Automatizado en facebook.

Entonces, ¿qué puedo hacer con testNg? Lo principal que nos da testNG es la capacidad de usar annotations en nuestros métodos para poder configurar nuestras ejecuciones de diferentes maneras. Vamos a verlo con un ejemplo concreto sin código, para poder entender mejor algunas cosas que podemos hacer con testNg:

Ejemplo 1: Agrupar casos de prueba en categorías, como smoke y regression

@Test(groups = { "smoke" })
 public void test1() {
   System.out.println("test1");
 }

@Test(groups = { "smoke" })
 public void test1() {
   System.out.println("test2");
 }

@Test(groups = { "regression" })
 public void test1() {
   System.out.println("test3");
 }

En este ejemplo, estamos usando la anotación @Test para indicarle a testNG que el método que viene a continuación es un test, y dentro de la anotación, asignamos un grupo determinado a cada test, por ejemplo, smoke o regression. De esta forma podemos ejecutar solamente un grupo, o dos, o los que queramos, sin tener que modificar código.

Ejemplo 2: Pasar un parámetro a un caso de prueba

@Test(groups = { "regression" })
@parameters({"parametro_1"})
 public void test1(String parametro_1) {
   System.out.println("El parametro es " + parametro_1);
 }

En este caso, tenemos un método llamado test1, perteneciente al grupo regression, que recibe un parámetro, y el valor de ese parámetro va a ser el valor que le demos a parametro_1 en nuestra suite de casos de prueba (más adelante vamos a ver eso).

Ejemplo 3: Priorizar casos de prueba

@Test(priority=1)
 public void test1() {
   System.out.println("Test 1");
 }

@Test(priority=2)
 public void test1() {
   System.out.println("Test 2");
 }

En este caso, estamos utilizando priority dentro del annotation test para decirle a testNg qué prioridad le debe dar a cada caso de prueba. En este caso, salvo que estemos corriendo en paralelo, ambos casos se van a ejecutar secuencialmente, en el orden test1 – test2. Podemos tener tantos métodos como queramos, y en caso de que compartan la prioridad, estos últimos se van a ejecutar de acuerdo al orden alfabético.

Anotaciones before/after test/suite

Además del uso de anotaciones para indicar tests y valores asociados a ellos, podemos realizar otros tipo de acciones, por ejemplo, utilizar las anotaciones @beforeSuite, @afterSuite, @beforeTest, @afterTest, etc, para ejecutar un método antes o después de una suite o un test.

@beforeSuite
 public void test1() {
   System.out.println("Starting");
}

@afterSuite
 public void test1() {
   System.out.println("Ending");
 }

@Test(priority=1)
 public void test1() {
   System.out.println("Test 1");
 }

@Test(priority=2)
 public void test1() {
   System.out.println("Test 2");
 }

En el ejemplo mencionado arriba, se van a ejecutar en el siguiente orden:

Starting
Test 1
Test 2
Ending

de acuerdo a cómo le indicamos a testNG que ejecute nuestra suite, utilizando beforeSuite y afterSuite.

computadora

Integrando testNG a nuestro proyecto

En el pasado artículo sobre automatización de software, hablamos de cómo empezar a automatizar pruebas, y en el utilizamos herramientas como Maven, Selenium Webdriver y Java.

Ahora, vamos a integrar testNG para poder ejecutar nuestros tests creados anteriormente.

Cómo agregar la dependencia de testNG a Maven

Para poder utilizar testNG en nuestro proyecto, vamos a agregar la dependencia correspondiente en el archivo POM.xml, el cual quedará de la siguiente manera:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.elblogdesanti.selenium</groupId>
	<artifactId>seleniumdemo</artifactId>
	<packaging>jar</packaging>
	<version>1.0-SNAPSHOT</version>
	<name>seleniumdemo</name>
	<url>http://maven.apache.org</url>

	<properties>
		<maven.compiler.target>1.8</maven.compiler.target>
		<maven.compiler.source>1.8</maven.compiler.source>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>
	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>3.8.1</version>
		</dependency>
		<dependency>
			<groupId>org.seleniumhq.selenium</groupId>
			<artifactId>selenium-java</artifactId>
			<version>3.141.59</version>
		</dependency>
		<dependency>
			<groupId>org.testng</groupId>
			<artifactId>testng</artifactId>
			<version>6.8</version>
		</dependency>
	</dependencies>
</project>

Luego, ejecutamos el comando:

mvn clean install && mvn eclipse:eclipse

para que se descargue la dependencia de testNG.

Utilizar la anotación @Test para ejecutar nuestros casos de prueba

En el primer ejemplo teníamos un caso de prueba que ejecutabamos a través del metodo main(), pero al utilizar la anotación @Test no es necesario utilizar main() para lanzar las pruebas. Vamos a crear una nueva clase para no cambiar la que usamos en el primer ejemplo, y le vamos a poner SeleniumTests.

Una vez creada la clase, vamos a copiar el caso de prueba que escribimos antes, sin el main() pero con la anotación @Test

package com.elblogdesanti.selenium;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.Test;

public class SeleniumTests {
	
	@Test
    public void myFirstTest()
    {
    	WebDriver driver = new ChromeDriver();
        driver.get("http://elblogdesanti.com");
        driver.findElement(By.className("cs-icon-search")).click();
        driver.findElement(By.className("search-field")).sendKeys("la regla de los dos minutos");
        driver.findElement(By.className("search-submit")).click();
    }

}

Ahora vamos a ejecutar el test utilizando testNG, para ello recomiendo tener el plugin de testNG instalado en Eclipse. Si no lo tienen, lo pueden descargar de acá.

Hacemos click derecho en el nombre de nuestra clase y seleccionamos Run As —> TestNG Test.

Listo, nuestro test ahora se ejecuta utilizando testNG.

Cómo crear una suite con testNG

Ahora vamos a crear un archivo xml, al cual llamaremos suite.xml, y utilizaremos para configurar nuestros tests:

<!DOCTYPE suite SYSTEM “https://testng.org/testng-1.0.dtd” >

<suite name="MyFirstSuite" verbose="1" >

  <test name="MyRegression">
    <classes>
      <class name="com.elblogdesanti.selenium.SeleniumTests"/>
    </classes>
  </test>
</suite>

Listo, ahora podemos hacer click derecho sobre la suite.xml y seleccioar Run As —> TestNG Suite.

Utilizando anotaciones de testNG

Ahora vamos a hacer algo un poco más complejo, y un poco mejor pensado, ya que si se fijan en el ejemplo de arriba tenemos un solo test, y este test se encarga de abrir el navegador, sin embargo cuando tengamos mas tests se va a volver repetitivo tener que escribir en cada uno de ellos la línea de abrir el navegador y navegar al sitio, además de que si tenemos que cambiar algo vamos a tener que hacerlo N veces.

Vamos entonces a utilizar BeforeMethod y AfterMethod para poder hacer lo siguiente por cada test:

  1. Lanzar el navegador y navegar al sitio
  2. Ejecutar el test en sí
  3. Cerrar el navegador

Para ello entonces dejamos el código de la siguiente manera (agregué un test para que tenga más sentido):

package com.elblogdesanti.selenium;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

public class SeleniumTests {
	
	WebDriver driver;
	
	@BeforeMethod
	public void start() {
		driver = new ChromeDriver();
        driver.get("<http://elblogdesanti.com>");
	}
	
	@AfterMethod
	public void end() {
		driver.close();
	}
	
	@Test
    public void myFirstTest()
    {
        driver.findElement(By.className("cs-icon-search")).click();
        driver.findElement(By.className("search-field")).sendKeys("la regla de los dos minutos");
        driver.findElement(By.className("search-submit")).click();
    }
	
	@Test
    public void mySecondTest()
    {
        driver.findElement(By.className("cs-icon-search")).click();
        driver.findElement(By.className("search-field")).sendKeys("la tecnica pomodoro");
        driver.findElement(By.className("search-submit")).click();
    }

}

Esto entonces va a ejecutar el start, seguido de un test y finalizando con el end, donde se cierra el navegador, esto lo va a hacer dos veces, una por cada test.

Proyecto de referencia

Voy a dejar el proyecto sobre el que yo estuve trabajando para estos tutoriales disponible en mi GitHub personal, siéntanse libres de clonarlo desde este enlace y de usarlo como base para las prácticas.

También los invito a que se sumen a nuestro gupo de facebook, Testing Automatizado.

3 comments

Comments are closed.