Anda di halaman 1dari 8

¿Qué es jUnit?

jUnit es un frameword java que permite la realización de la ejecución de clases de manera controlada,
para poder comprobar que los métodos realizan su cometido de forma correcta.

También sirve como herramienta para realizar las pruebas de regresión, que realizaremos cuando una
parte del código ha sido modificada y sea necesario comprobar que se sigue cumpliendo con todos os
requisitos.

¿Por qué usar Test?

Supongamos que nos encontramos en un grupo de desarrollo en el que hay varios programadores, y
cada uno trabaja en un módulo/componente de la aplicación de manera independiente, pero a su vez
todos los módulos están interrelaciados.

Bien primero diremos que existen 2 tipos de pruebas que tendremos que realizar:

 Pruebas unitarias. Son pruebas que comprueban la funcionalidad del módulo de forma independiente al resto
de la aplicación.
 Pruebas de integración. En estas pruebas comprobaremos la correcta integración de los módulos,
comunicación, llamadas etc…

Si realizamos algún cambio sobre alguno de los módulos como podemos estar seguros que con esta
nueva versión no hemos incluido algún fallo. La única forma sería repasar manualmente una a una todas
las funcionalidades de la aplicación.

Este proceso de regresión puede ser largo y tedioso, así que porque no automatizamos este proceso de
pruebas, de esta forma ahorramos en tiempo y nos aseguramos de que se han ejecutado todas las
pruebas necesarias para considerar que la aplicación esta correcta.

Versiones de jUnit

Actualmente existen 2 versiones claramente diferenciadas dentro de jUnit:

 3.x
 4.x
¿Qué diferencias existen básicamente entre ambas? Principalmente la diferencia es que a partir de la
versión 4.x se introdujo el uso de anotaciones para la declaración de las pruebas.

Ahora pasamos a explicar de una manera más extensa cada una de las versiones.

jUnit 3.x

Para crear una clase de test tendremos que heredar de TestCase de jUnit, con esta herencia estamos
indicando que se trata de una clase de test.

import junit.framework.TestCase

...

public class TestPrincipal extends TestCase {

...

Ahora incluiremos dentro cada uno de los test que realizaremos sobre la clase. En jUnit 3.x para
diferenciar entre los métodos que son test y los que son auxiliares tendremos que usar el prefijo “test”.

Para cada uno de los test tendremos que realizar una operación y comprobar el resultado devuelto es el
correcto, para realizar este cometido la clase TestCase nos proporciona varios métodos de verificación:

 assertArrayEquals: Comprueba si 2 arrays son iguales. Devuelve assertionError en caso de no serlo.


 assertEquals: Comprueba que 2 valores de tipo numérico sean iguales. Devuelve assertionError en caso de no
serlo
 assertTrue: Comprueba que la condición se cumple. Devuelve assertionError si no se produce el resultado
esperado.
 fail: devuelve una alerta informando que el test ha fallado.

Además existen 2 métodos que nos servirán para inicializar cada una de las pruebas y liberar recursos
que nos hallan echo falta. Estos métodos son: setUp y tearDown.

Estos métodos se ejecutan antes de cada test (setUP) y al finalizar cada uno de los test(tearDown).

jUnit 4.x

Como ya hemos comentado antes, la principal diferencia con la versión 3.x es la inclusión de
anotaciones. De esta manera para crear una clase de test nos servirá cualquier clase.
Para crear un test dentro de una clase solo le añadimos la anotación “@test”, ahora ya no es necesario
que el nombre del método tenga una nomenclatura concreta.

Además de las funciones setUp y tearDown comentadas en la versión 3.x han añadido 2 más que se
ejecutarán una sola vez al inicio de los test “setUpClass” y una sola vez al finalizar todos los test
“tearDownClass”.

A continuación detallamos el resto de anotaciones existentes:

 @RunWith: Se le asigna una clase a la que JUnit invocará en lugar del ejecutor por defecto de JUnit.
 @Before: Indicamos que el siguiente método se debe ejecutar antes de cada test (precede al método setUp).
Si tiene que preceder al método setUpClass, la notación será “@BeforeClass”
 @After: Indicamos que el siguiente método se debe ejecutar después de cada test (precede al método
tearDown). Si tiene que preceder al método tearDownClass, la notación será “@AfterClass”
 @Test: Indicamos a Junit que se trata de un método de Test. En versiones anteriores de JUnit los métodos
tenían que tener un nombre con la siguiente estructura: “test”. Con esta notación colocada delante de los
métodos podemos elegir el nombre libremente.

Integraciones de jUnit

Eclipse

La inmensa mayoría de los IDE de desarrollo se integran con jUnit facilitándonos el trabajo con el
framework. Eclipse no es ninguna excepción así que ahora veremos en que nos ayuda.

Eclipse nos facilita tanto la creación de nuevas clases de test gracias a un wizard muy completo, y la
ejecución de de los test.

Para utilizar el wizard de creación de test solo tendremos que irnos al proyecto y hacer click con el botón
derecho y seleccionar nuevo > jUnit test case. Entonces eclipse nos mostrará la siguiente ventana.
Como podemos ver en la imagen desde aquí podremos configurar tanto la versión de jUnit, la clase
sobre la que queremos ejecutar los test e incluso algunas de las funciones principales de la librería
(setUp, tearDown, etc.).

Una vez tenemos creadas todas nuestras clases de test si deseamos ejecutarlas solo tendremos que
hacer click con el botón derecho en el test y entrar en run > jUnit test case.
Maven

Para que los test automáticos cumplan su función, es muy importante ejecutar los con mucha frecuencia,
especialmente mientras estamos modificando código. Aunque eclipse nos ayuda en esta tarea no es
suficiente ya que somos nosotros los que tenemos que lanzar los test manualmente. Por ello, son
interesantes herramientas como maven.

Dentro de la estructura de directorios que poseen los proyectos de maven ya existe una ruta específica
para los test (“src/test/java”). Maven detecta automáticamente todos los test que dejemos en dicha ruta y
los ejecutará cada vez que le solicitemos una compilación. Si alguno de los test diera un fallo maven nos
devolvería un error y no continuaría con la compilación.

Gracias a esta funcionalidad podremos detectar de una manera muy prematura algún fallo que pueda
contener nuestro código.

Ant

Aunque ant también dispone de integración con jUnit no es tan sencilla de usar como con maven. Para
que Ant ejecute los test que tenemos generados deberemos incluir una nueva tarea en nuestro build.xml.

Un ejemplo de cómo debe de ser dicha tarea es el siguiente:

<target name = "junit" depends = "init">


<javac
encoding = "ISO-8859-1"
destdir = "${junit.build.dir}"
classpathref = "lib.jarfiles"
debug = "on"
deprecation = "on"
optimize = "on">
<src path = "${src.dir}" />
<src path = "${test.dir}" />
</javac>

<junit fork="no" printsummary="no" haltonfailure="no" showoutput="true"


filtertrace="false">
<classpath refid="lib.jarfiles" />
<classpath>
<pathelement path = "${java.class.path}" />
<pathelement path = "${junit.build.dir}" />
</classpath>

<batchtest todir="${junit.report.dir}">
<fileset dir="${junit.build.dir}">
<include name="org/farng/mp3/AllTestCase.class" />
</fileset>
<formatter type="xml" />
</batchtest>
</junit>
</target>

La tarea está dividida en dos bloques: la compilación de las pruebas (javac) y la ejecución y generación
del reporte (junit).

En la primera etapa se compilan el directorio de pruebas unitarias (${test.dir}) y el código fuente de la


aplicación (${src.dir}), este último para resolver las dependencias que tienen con él las pruebas unitarias.
En la segunda etapa usamos el tag junit y le indicamos a través del classpath las ubicaciones de las
librerías que requiere el proyecto (incluyendo las de JUnit) y la ubicación de las pruebas unitarias que
ejecutará (junit.build.dir). Note que este último directorio debe coincidir con el destino (destdir) de la
primera parte de la tarea (${junit.build.dir}). Después con el tag batchtest realizamos la ejecución de la
prueba.

Aunque son varias pruebas unitarias y archivos, todas se ejecutan con org/farng/mp3/AllTestCase.

La integración de jUnit y Ant existe de la versión 1.7 de Ant.

Spring

¿Como se trabaja con jUnit si estamos utilizando un inyector de dependencias como Spring?

Para realizar tal tarea como mínimo tendríamos que levantar el contenedor de dependencias. Spring ya
nos proporciona esta funcionalidad gracias a 2 clases:
 AbstractTransactionalJUnit4SpringContextTests: da soporte para injección de dependencias.
 AbstractTransactionalDataSourceSpringContextTests: a parte de darnos soporte para la injección crea una
transacción por cada test y hace un rollback al terminar, de esta forma no deja información enla BBDD.
En ambos casos tendremos que añadir la anotación @ContextConfiguration con la ruta hasta el fichero
de configuración de spring. De aquí será donde lea la configuración de los bean a cargar.
Para poder cargar algún bean solo tendremos que crear un atributo que se llame igual que el id del bean
de spring y añadirle la anotación @Autowired.

Por ejemplo:

@Autowired
private MercadoIntradiarioAction manejadorMercadoIntradiario;

@Autowired
private MercadoIntradiarioService mercadoIntradiarioService;

Mock objects

Existen algunas situaciones en las que realizar los test unitarios y de integración no es nada trivial,
debido a la complejidad de la aplicación o por su diseño. Para paliar un poco estas situaciones se sueñe
utilizar una estrategia con “Mock objects” u objetos simulados.

Esta estrategia consiste en generar objetos que cumplan con la interfaz que necesitemos pero sin
implementación. Para realizar este cometido existen numerosas librerías en java. Algunas de ellas son:

 jMock – http://www.jmock.org/
 Mockito – https://code.google.com/p/mockito/
 EasyMock – http://easymock.org/

Test drive development (TDD)

Para asegurarnos que la aplicación funciona correctamente y sin ningún bug, la única manera es realizar
todas las pruebas posibles en todos los escenarios. Como ya hemos comentado esto es un trabajo largo
y tedioso, con lo que optamos por la realización de pruebas automáticas. Pero ¿como podemos
asegurarnos de que hemos cubierto el 100% del código con pruebas? La manera más eficiente de
lograrlo es escribir las pruebas antes que el código. De aquí nace la metodología TDD o Test drive
development.

Test drive development o TDD a partir de ahora, es una metodología de diseño e implementación de
software, esta metodología se centrada en 3 pilares básicos:
 La implementación de las funciones justas que el cliente necesita y no más.
 La minimización del número de defectos que llegan al software en fase de producción.
 La producción de software modular, altamente reutilizable y preparado para el cambio.

TDD sigue un sencillo algoritmo de 3 pasos:

1. Escribir la especificación del requisito (el ejemplo, el test).


2. Implementar el código según dicho ejemplo.
3. Refactorizar para eliminar duplicidad y hacer mejoras.

Una vez terminado los 3 pasos el algoritmo realizamos otra iteración completa, y así sucesivamente
hasta que abarcamos el 100% de los requisitos.

Podéis encontrar más información sobre esta metodología agil en el libro “Diseño Agil con TDD” de
Carlos Blé Jurado.

Anda mungkin juga menyukai