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 Petróleo=Unidad

JAXB: Leer y escribir ficheros XML

Muchas veces en nuestras aplicaciones debemos manejar documentos XML ( Extensible Markup Language ). Este lenguaje se ha convertido en un estándar para intercambio de datos entre programas y aplicaciones a través de Internet. En un esquema XML (o  XSD ) podemos definir los elementos que pueden aparecer en un documento XML así como las relaciones entre los mismos. JAXB ( Java Architecture for XML Binding ) es un estándar Java para transformar un esquema XML (o  XSD ) en una representación a objetos java. Mediante la API de JAXB podemos mapear un objeto Java a un documento XML ( "marshall" ) y el proceso contrario, es decir, a partir de un esquema XML crear su conjunto de objeto Java asociado ( "unmarshall" ). JAXB Resumiendo lo que nos proporciona JAXB es: Generación de objetos Java a partir de un XSD a través de un compilador Proporciona capacidades de marshall/unmarshall (escribir fichero XML desde java y al contrario) Integración con Maven a través de xj

Matemáticas y cine.

El otro día estaba viendo por la televisión una película llamada 21 blackjack . En una escena de la película el profesor de matemáticas ( Kevin Spacey ) le presenta a uno de sus alumnos la siguiente situación: se encuentra en un concurso en la que debe escoger entre tres puertas (1,2 y 3). En dos de ellas hay una cabra, sin embargo en una de las 3 hay un flamante coche nuevo. El alumno responde que quiere abrir la puerta. El presentador, conocedor de lo que hay detrás de cada puerta decide abrir otra puerta diferente mostrando detrás de ella una cabra. El profesor se dirige al alumno y le pregunta, ¿cambiarías la puerta o te quedarías con la puerta que tienes? Muchos de nosotros cambiaríamos de puerta pensando que es una treta del presentador para engañarnos. ¿Cual elegiríais vosotros? Al comienzo tenemos 1/3 de probabilidades de acertar la puerta donde está el coche. Una vez que el presentador abre la puerta con una cabra, la mayoría de gente piensa que hay la misma probabilidad de