Ir al contenido principal

TUTORIAL TESTNG: FRAMEWORK PARA TUS TESTS

TestNG (Next Generation) es un framework de testing inspirado en JUnit y NUnit pero introduciendo nuevas caractarísticas como los test de dependencia y el concepto de grouping. Su uso nos permite realizar todas las categorías de test como pruebas unitarias, de integración, end-to-end, pruebas funcionales, etc...





Instalación en Eclipse

Instalar el plugin de TestNG para Eclipse es sencillo. En mi caso es Eclipse JUNO y únicamente para instalarlo lo único que tenemos que hacer es buscarlo con la herramienta Eclipse MarketPlace y pulsar el botón de Install.



Crear una clase para nuestros test con TestNG es igualmente sencillo. En nuestro proyecto creamos una nueva clase TestNG. Pulsamos NEXT y después seleccionamos las anotaciones que deseamos que aparezcan en nuestra clase:



Cuando creamos nuestra clase TestNG nos dará fallos en las anotaciones. Esto es porque debemos incluir en nuestro proyecto las librerías del framework. Para ello pulsamos sobre las Properties de nuestro proyecto y en Java Build Path añadimos la librería de TestNG.


Ejemplo con anotaciones básicas

A continuación repasamos las anotaciones básicas y un ejemplo con su resultado:

  • @BeforeClass. Código ejecutado antes de ejecutar los test. Aquí se podría inicializar por ejemplo alguna fuente de datos para utilizarla en nuestros test.
  • @AfterClass. Código ejecutado después de ejecutar todos nuestros test. Aquí se podrían cerrar todos los recursos que hemos abierto en el código bajo la etiqueta @BeforeClass.
  • @BeforeMethod. Código ejecutado antes de cada test.
  • @AfterMethod. Código ejecutado después de cada test.
  • @Test. Indica que el método es un test.

Un ejemplo:

package es.jpascu.testng;

import java.util.ArrayList;
import java.util.Collection;

import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

public class TestNGBasic {
 private Collection collection;

 @BeforeClass
 public void oneTimeSetUp() {
  // one-time initialization code
  System.out.println("@BeforeClass - oneTimeSetUp");
 }

 @AfterClass
 public void oneTimeTearDown() {
  // one-time cleanup code
  System.out.println("@AfterClass - oneTimeTearDown");
 }

 @BeforeMethod
 public void setUp() {
  collection = new ArrayList();
  System.out.println("@BeforeMethod - setUp");
 }

 @AfterMethod
 public void tearDown() {
  collection.clear();
  System.out.println("@AfterMethod - tearDown");
 }

 @Test
 public void testEmptyCollection() {
  Assert.assertEquals(collection.isEmpty(), true);
  System.out.println("@Test - testEmptyCollection");
 }

 @Test
 public void testOneItemCollection() {
  collection.add("itemA");
  Assert.assertEquals(collection.size(), 1);
  System.out.println("@Test - testOneItemCollection");
 }

}

Ejemplo con características avanzadas

En este ejemplo añadimos otros ejemplos de características avanzadas que se se pueden utilizar en nuestros tests con TestNG:

  • @Test(expectedExceptions=TipoException.class). El test unitario pasa aunque en el test se lanza la excepción de tipo TipoException.class.
  • @Test(enabled=false). El test unitario no se ejecuta.
  • @Test(timeout=1000). Si tarda más de 1 segundo el test unitario pasará como FAILED, pero nos aseguramos que finalice su ejecución.
Un ejemplo:




package es.jpascu.testng;

import org.testng.annotations.Test;

public class TestNGAdvanced {

 @Test(expectedExceptions = NullPointerException.class)
 public void testException() {
  String s = null;
  s.charAt(0);
 }

 @Test(enabled = false)
 public void testIgnore() {
  System.out.println("Esto no se ejecuta!!");
 }

 @Test(timeOut = 1000)
 public void testBucleInfinito() {
  while (true)
   ;
 }

}

Ejemplo con parámetros básicos y complejos

Podemos definir una suite, que es un XML en el que entre otras cosas se pueden definir varios clases de test que se ejecuten juntas. Además podemos definir parámetros simples (int, float) como objetos complejos (ArrayList, String, etc..).


Primero vemos un ejemplo en el que se define un parámetro de tipo int en el suite.xml que estará disponible en la ejecución de nuestras clases de test. Para definirlo en nuestro test se emplea la anotacion @Parameters.


package es.jpascu.testng;

import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

public class TestNGBasicParameter {
  @Test
  @Parameters(value="number")
  public void testWithBasicParameter(int number) {
   System.out.println("El valor del paámetro es: " + number);
  }
}


  
     
 
    
       
    
   
 
Ahora vemos como TestNG gestiona el paso de parámetros complejos. Para ello se utiliza la anotación @DataProvider. En el ejemplo vemos como se pasan tipos complejos como colecciones.



package es.jpascu.testng;

import java.util.ArrayList;

import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

public class TestNGComplexParameter_1 {
 @Test(dataProvider = "dp")
 public void parameterArrayListInTest(ArrayList list) {
    System.out.println("Primer Elemento Lista : " + list.get(0));
    System.out.println("Segundo Elemento Lista : " + list.get(1));
 }
 
 //This function will provide the parameter data
 @DataProvider(name = "dp")
 public Object[][] parameterIntTestProvider() {
  ArrayList lista = new ArrayList();
  lista.add("1");
  lista.add("2");
  return new Object[][]{
    
     {lista}
        };
 }
}


En este otro ejemplo vemos como se pasa un POJO como parámetro:


package es.jpascu.testng;

public class Pojo {
 private int numero;
 
 private String mensaje;

 public Pojo(int numero, String mensaje) {
  super();
  this.numero = numero;
  this.mensaje = mensaje;
 }

 public int getNumero() {
  return numero;
 }

 public void setNumero(int numero) {
  this.numero = numero;
 }

 public String getMensaje() {
  return mensaje;
 }

 public void setMensaje(String mensaje) {
  this.mensaje = mensaje;
 }
 
 
}

package es.jpascu.testng;

import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

public class TestNGPojoParameter_1 {
 @Test(dataProvider = "dp")
 public void parameterPojoListInTest(Pojo obj) {
    System.out.println("Pojo - numero : " + obj.getNumero());
    System.out.println("Pojo - mensaje : " + obj.getMensaje());
 }
 
 //This function will provide the parameter data
 @DataProvider(name = "dp")
 public Object[][] parameterPojoTestProvider() {
  Pojo pojo = new Pojo(1, "Hola");
  
  return new Object[][]{
    
     {pojo}
        };
 }
}

Concepto de grouping

En este apartado vemos un ejemplo del concepto de grouping que no existe en JUnit 4. Por ejemplo, imaginemos que tenemos una clase de test en la que probamos operaciones a LDAP y a bases de datos. Podemos ejecutar los test agrupados por su funcionalidad, en nuestro caso, LDAP y BBDD. Si queremos ejecutar sólo los test relacionados con LDAP haríamos lo siguiente:


package es.jpascu.testng;

import org.testng.annotations.Test;

public class TestConnection {

 @Test(groups="ldap")
 public void testLDAP_OP1() {
  System.out.println("Method - testLDAP_OP1");
 }

 @Test(groups="ldap")
 public void testLDAP_OP2() {
  System.out.println("Method - testLDAP_OP1");
 }

 @Test(groups="bbdd")
 public void testBBDD_Oracle() {
  System.out.println("Method - testBBDD_Oracle");
 }

 @Test(groups="bbdd")
 public void testBBDD_SQLServer() {
  System.out.println("Method - testBBDD_SQLServer");
 }
}



      
        
      
    
    
        
    
  


Test Dependientes

Otro concepto que añade TestNG son los  test dependientes. Podemos definir en nuestras clases de test que un método de test determinado dependa de uno o varios métodos de test. Para ello utlizamos el atributo dependsOnMethod.


Aquí os pongo un ejemplo en el que nuestro testA depende del testB y el testC.


package es.jpascu.testng;

import org.testng.annotations.Test;

public class TestNGDepends {

 @Test(dependsOnMethods={"testB","testC"})
 public void testA() {
  System.out.println("testA");
 }

 @Test
 public void testB() {
  System.out.println("testB");
 }

 @Test
 public void testC() {
  System.out.println("testC");
 }

}

Conclusiones. JUnit4 vs TestNG.

Por último os pongo una tabla comparativa entre JUnit4 y TestNG para observar la funcionalidad que cubre cada uno de los dos frameworks:



TestNG es superior en los test de grupo, en parametrización de objetos complejos y en los test de dependencia además de cubrir todas las funcionalidades de JUnit 4

Otro punto a su favor es que para ejecutar varios ficheros de test juntos (Suite Test) se realiza mediante la definición de un fichero XML y no mediante anotaciones en una clase Java como se hace en JUnit 4. Además se puede integrar perfectamente con herramientas tan utilizadas como Maven o Selenium. 

En general se puede recomendar la utilización de este framework en lugar de JUnit 4 ya que cubre toda la funcionalidad de este último, es más flexible y añade nuevas capacidades.

Salu2.

Fuente: mkyong

Comentarios

Entradas populares de este blog

Soluciones Alchemy Classic 389 elementos

Hace algún tiempo salió una actualización del Juego Alchemy Classic en la que aparecían más elementos (389 en lugar de 238). Aparte de añadir elementos mejoran algunas traducciones en castellano y mejoran la interfaz, aunque todavía hay algún error en algunos nombres de elementos. Aquí os dejo las soluciones para los que estén atascados y no puedan dormir por las noches: Sustancia primaria Aire=Elemento primario  Fuego=Elemento primario  Agua=Elemento primario  Tierra=Sustancia Primaria Arena=Piedra + Aire Piedra=Tierra + Fuego Arcilla=Arena + Pantano Caliza=Tierra + Amonitas Carbono=Fuego + Madera Cloro=Fuego + Sal + Electricidad CO2(Dióxido de Carbono)=Ceniza + Ácido nítrico Electricidad=Relámpago+ Metales Gas natural= Yacimiento de gas + Pozo Helio=Refinería de gas + Gas Natural Hidrógeno=Electricidad + Agua Hielo=Frío + Agua Imán=Piedra + Metales Metano=Deshechos Vegetales + Pantano Oxígeno=Electricidad + Agua Pe...

Soluciones Alchemy Classic 442 elementos

Después de la resaca navideña y de la cuesta de enero, volvemos para informar la agradable sorpresa que nos ha dado a los fans de Alchemy Classic la empresa NIASOF ,  tras actualizar el juego Alchemy Classic. Una nueva versión con 442 elementos , interfaz mejorada de grupos y lo más importante, nuevos elementos que descubrir. La gran novedad de esta actualización son los puntos que tienes asignados , con los que puedes  conseguir pistas sobre los elementos que no has abierto todavía como: Conseguir un subelemento de un elemento, con 100 puntos . Conseguir el grupo de un subelemento de un elemento (qué lío , jeje), con 35 puntos . Me gusta, me gusta el enfoque de esta nueva versión aunque los elementos que han sacado me parecen poco originales. Parece que se van agotando las ideas para los elementos nuevos. Aquí van las soluciones: Carbon = Tierra + Turba Sol = Estrella + Tierra Espacio = 3 x Estrella Estrella = Helio + Hidrógeno Oso Pa...

Alchemy Classic

Dentro de los juegos que he descargado con el Android Market hay dos que destacan sobre todos los demás. El primero es Angry Birds (pájaros furiosos), en el cual comandas un ejercito de pájaros para luchar con una piara de cerdos malotes los cuales han robado sus huevos. Básicamente, tienes que ir pasando nivel tras nivel afinando tu puntería lanzando los pájaros a los cerdos que se esconden tras maderas, cristales y piedras. Pero la verdadera joya que no es tan conocida es Alchemy Classic . En este juego puedes desempeñar el papel  de Dios. Comenzando con 4 elementos básicos, Aire, Agua, Tierra y Fuego tienes que ir obteniendo todos los demás elementos de la creación (animales, plantas, herramientas...) mediante la combinación de los 4 primeros. En total hay 238 elementos. Después de una semana y alguna noche sin dormir por fin los he obtenido todos. El último elemento me ha llevado más de la cuenta por su maravillosa traducción. ¿Qué son abrojos? ¿Lo sabéis? Pues no, ...