Buscar
Social
Ofertas laborales ES
sábado
sep012001

Introduccrión a JUnit


Introducción a JUnit


Fecha de creación: 01.09.2001

Revisión 1.0 (01.09.2001)

DySs Ashter
dyss AT java DOT zzn DOT com

Copyright (c) 2002, Alberto Molpeceres. Este documento puede ser distribuido solo bajo los términos y condiciones de la licencia de Documentación de javaHispano v1.0 o posterior (la última versión se encuentra en /licencias/).





Cualquier codigo que escribamos deberia ser testeado. No podemos dar por finalizada la implementacion de una clase sin estar seguros de su buen funcionamiento. Esto implica que el codigo no tenga errores de programacion y que ademas realice exactamente lo que nosotros esperamos de el. La unica forma es hacer una serie de test que verifique el codigo que acabamos de escribir. Seguramente todo el mundo testea de alguna manera o otra el codigo. ¿Quien no ha metido System.out.println en el codigo para visualizar estados de variables y asi comprobar que todo ha ido bien hasta ese punto? Pero existen formas mas avanzadas, eficientes y seguras de probar el codigo.


JUnit nos proporciona una forma sencilla, rapida y elegante de escribir test y validarlos de forma automatica. A continuacion os explicare que nos ofrece JUnit.





En la página de JUnit[1] podemos encontrar la ultima version de junit, actualmente la 3.7. Para poder usar Junit lo unico que debemos hacer es incluir el fichero junit.jar en nuestro classpath.


La forma de funcionar tipica de un test con JUnit es: definir unos datos, darles algun tipo de tratamiento, obtener unos resultados y comprobarlos con los resultados que nosotros estabamos esperando. La idea final es que sea el propio JUnit el que no diga si el test ha ido bien o por el contrario el resultado no coincide con el esperado.


Veamos como hacerlo.





Empezaremos viendo como se pueden hacer las comprobaciones de los resultados. La clase junit.framework.Assert, nos proporciona una serie de metodos que son los encargados de hacer dichar comprobaciones. Esta clase contiene una serie de metodos que empiezan por assert. Tenemos metodos assert para comprobar si dos objetos son iguales (assertEquals...), para comprobar si un objeto es nulo (assertNull...), para comprobar si un objeto no es nulo (assertNotNull...) o para comprobar si dos variables apuntan a un mismo objeto (assertSame...).


Cada llamada a un metodo assert podemos considerarla como un test. La logica de estos metodos es simple, si la condicion del metodo assert se cumple el test es valido, en caso contrario el test no es valido y lanza un FailedAssertionError, o sea, un error en el testeo.


Debemos tener cuidado con los bloques try-catch, ya que estos bloques normalmente capturan excepciones que lanza nuestro codigo indicando alguna anomalia. Si en los test usamos algun bloque de este tipo no deberiamos dejar que el test acabe bien. Para este proposito disponemos del metodo fail() o fail(String mensaje), que lanza un FailedAssetionError, y nos informe de la anomalia.





La clase abstracta junit.framework.TestCase es la base sobre la cual definiremos nuestros tests. Esta clase extiende de junit.framework.Assert.


Para crear un test con JUnit debemos seguir estos tres pasos:


  • Crear una clase que herede de la clase TestCase

        public class SimpleTest extends TestCase




  • Crear un constructor con un parametro de tipo String y llamar al constructor de la clase padre pasandole dicho String.

        public SimpleTest( String nombre ) {
    super( nombre )
    }




  • Crear uno o varios metodos que empiecen por "test", sin parametros y que no devuelvan nada.

        public void testSimple() {
    ...
    }



Formas de crear tests.


De esta forma tan simple hemos creado una clase de test. Ahora solo nos queda implementar el metodo testSimple().

import junit.framework.TestCase;

public class SimpleTest extends TestCase {

public SimpleTest( String nombre ) {
super( nombre );
}

public static void main( String args[] ) {
junit.textui.TestRunner.run( SimpleTest.class );
}

public void testSimple() {
String s1 = "DySs";
String s2 = "DySs";
assertEquals( s1, s2 );
}

}



Como hemos visto un TestCase no es mas que una clase que contiene uno o varios metodos test...() donde aparecen una o varias llamadas a metodos assert...() o fail().


La ejecucion de un test puede acabar de cuatro formas:

  • Con la validacion correcta de todos los asserts. Esto es lo que esperamos.
  • Lanzando uno a varios FailedAssertionError con su informacion asociada. Esto ocurre si algun assert no ha sido valido, o sea, la ejecucion de nuestro codigo no ha devuelto el resultado esperado.
  • Lanzando cualquier Exception de Java. Esto no es probocado por la validacion de los metodos assert, sino que nos indica algun error de implementacion, ya puede ser del propio TestCase o de nuestro codigo.
  • Puede que el resultado sea una mezcla de excepciones de Java y FailedAssertionErrors.
Formas de terminar un test.


Ejemplo:

import junit.framework.TestCase;

public class ErrorEnTryCatch extends TestCase {

public static void main( String args[] ) {
junit.textui.TestRunner.run( ErrorEnTryCatch.class );
}

public ErrorEnTryCatch( String nombre ) {
super( nombre );
}

public void testTryCatch() {
String error = null;
try {
System.out.println( error.toString() );
} catch( NullPointerException npex ) {
fail( "\nExcepcion capturada por el test\n" +
npex );
}
}
}






La secuencia de ejecucion de una clase que herede de TestCase es la siguiente:

  1. setUp()
  2. testAlgo()
  3. tearDown()
Secuenciad e ejecución de un test.


Esta secuencia se repite para todos los metodos test que contenga nuestra clase.


Si tuviesemos varios metodos test que realizan algun tratamiento sobre unos mismos datos, deberiamos usar setUp() para la inicializacion de dichos datos. En setUp() inicializaremos variables, estableceremos conexiones con bases de datos, etc. En tearDown() liberaremos recursos tales como las conexiones a bases de datos.



import junit.framework.TestCase;

public class SimpleTest2 extends TestCase {

private String s1;
private String s2;
private String s3;

public SimpleTest2( String nombre ) {
super( nombre );
}

public static void main( String args[] ) {
junit.textui.TestRunner.run( SimpleTest2.class );
}

public void setUp() {
s1 = "DySs";
s2 = "DySs";
s3 = "Ashther";
}

public void testComparaStrings() {
assertEquals( s1, s2 );
}

public void testConcatenaStrings() {
String test1 = s1 + s3;
String test2 = s2 + s3;
assertEquals( test1, test2 );
}

}






Es posible que tengamos nuestros tests estructurados en varias clases TestCase y nos interese ejecutarlos todos de una sola vez. Con este proposito JUnit nos proporciona la clase TestSuite que sirve para agrupar tanto TestCases como otras TestSuite.


Para crear una coleccion de tests debemos seguir los siguientes pasos:


  1. Crear una clase que herede de TestCase

        public class VariosTest extend TestCase




  2. Crear un constructor con un parametro de tipo String y llamar al constructor de la clase padre pasandole dicho String.

        public VariosTest( String nombre ) {
    super( nombre )
    }




  3. Crear un metodo estatico de nombre suite, sin parametros de entrada y que devuelva un Test.

        public static Test suite()




  4. Crear un TestSuite dentro del metodo suite

        TestSuite suite = new TestSuite();




  5. Añadir tests al TestSuite

        // Solo un metodo test
    suite.addTest( new SimpleTest2( "testConcatenaString" );
    // Todos los metodos test de un TestCase
    suite.addTestSuite( SimpleTest.class );
    // Otro TestSuite
    suite.addTest( MiTestSuite.suite() );




  6. devolver el TestSuite

        return suite;



Proceso de creación de una TEstSuite


Ejemplo:

import junit.framework.TestSuite;
import junit.framework.Test;
import junit.framework.TestCase;

public class VariosTest extend TestCase{

public VariosTest( String nombre ) {
super( nombre );
}

public static void main( String args[] ) {
junit.textui.TestRunner.run( suite() );
}

public static Test suite() {
TestSuite suite = new TestSuite();
suite.addTestSuite( SimpleTest.class );
suite.addTest( new SimpleTest2( "testConcatenaStrings" ) );
return suite;
}

}






Hasta ahora hemos visto como crear nuestros test, ahora veremos la forma de ejecutarlos. Todos los ejemplos tienen un metodo main donde se llama a junit.textui.TestRunner. TestRunner es la clase encargada de ejecutar nuestros tests. Disponemos de tres clases TestRunner, una en modo testo y dos mas en modo grafico, Swing y AWT.



public class VisualizaResultados {

public static void main( String args[] ) {
// Modo texto
junit.textui.TestRunner.run( SimpleTest2.class );
// Modo grafico con AWT
junit.awtui.TestRunner.run( SimpleTest2.class );
// Modo grafico con Swing
junit.swingui.TestRunner.run( SimpleTest2.class );
}
}






Conclusión


La forma ideal de usar JUnit es desarrollando en paralelo el codigo de la clase y el test JUnit para ese trozo de codigo, en vez de escribir toda la clase y luego escribir el test. Si desarrollamos en paralelo siempre nos sera mas facil depurar el codigo y testearlo mucho mejor, pero como he dicho es una forma de trabajar, no una obligacion.


Como hemos podido comprobar el uso de JUnit es muy sencillo y a la vez potente. Y esto es solo la punta de iceberg, podeis encontrar mucha mas informacion en su pagina oficial, www.junit.org, eso si, esta en inglés.



Recursos




[1] Web de JUnit.,
http://www.junit.org


Acerca del autor

DySs Ashter
DySs Ashter, desarrollador de EJBs en Barcelona dentro del desarrollo de una plataforma aseguradora en lo que es su primer trabajo como desarrollador JAVA.

viernes
ago312001

Sun presenta Forte for Java 3.0

Aquí esta disponible ya la nueva versrión de Forte for Java.

La 3.0 presenta una cantidad impresionante de modulos, tambrión para la versrión "Community". Entre ellos se pueden destacar los de programacrión avanzada de Servlets y JSP, integracrión con algunas herramientas Jakarta-Apache como Ant y Tomcat, un modulo de CVS, depuradores, y por supuesto para un monton de APIs de Java2 "estandar" y no tan estandar, como JDBC, RMI, JNDI, JAr, I18N, y mucho más.

Esta nueva versrión, que requiere el JSDK 1.3.1, sigue siendo gratis en la edicion "comunnity", y si algurión lo prueba espero que nos diga si se nota una mejora apreciable en el rendmineto.
jueves
ago302001

Xerces 2 for Java (beta 2)

Muchos de nosotros usamos Xerces como parser XML, asi que no deberýamos perder de vista la evolucrión de este popular parser de la seccion XML de la fundacrión Apache.

Esta nueva versrión será totalmente compatible con la anterior, pero se ha reescrito TODO para conseguir un mejor diseño y rendimiento.

Lo dicho, no perderla de vista.
miércoles
ago292001

Java 2 1.4 Beta 2, ya falta menos

Pues ya esta disponible la beta 2 del nuevo JSDK, el 1.4. En teoria deberýa ser la ýltima beta antes de la versrión final, pero nunca se sabe.

Aqui, en javaHispano, ya os tenemos preparado un articulo con las novedades que traerý el nuevo JSDK, disponible a partir del proximo sabado, 1 de Septiembre.
lunes
ago272001

JBoss 2.4 ya disponible!.

Pues ya esta disponible la versión 2.4 de JBoss, un aclamado servidor de aplicaciones J2EE opensource que se puede conectar con la mayoria de servidores web y de Servlets disponibles.
Resulta casi imposible numerar los infinitos cambios que aporta a la última versión estable (la 2.2.2), pero a parte de los habituales errores corregidos, se pueden destacar las nuevas funciones de seguridad, un controlador de tareas programables, y más soporte para JMS, Connector inclusive.