Está en la página 1de 23

JUNIT

Los problemas de las pruebas manuales 1

Primera prueba JUnit 4

Before y After 8

Asserts 10
Ejemplo 11

Expected y Timeout 13
expected 13
timeout 15

BeforeClass y AfterClass 16

Pruebas parametrizadas 18

Test Suite 20

Los problemas de las pruebas manuales


JUnit es un entorno para poder crear pruebas unitarias, básicamente es una librería que
nosotros podemos integrar en nuestro programa y en la cual podemos hacer determinados
asertos, que son instrucciones que verifican cosas. Con JUnit vamos a correr una serie de
pruebas que permita verificar de forma automática que un programa de ordenador esta bien
escrito y que no contiene bugs/defectos, es decir, que algo no funciona adecuadamente.

Creamos un Java Project llamado Calculadora, donde iremos haciendo pruebas unitarias
para comprobar que la calculadora está bien.
Dentro del proyecto creamos una clase llamada Calculadora y en el paquete calculadora.
A esta clase vamos a darle un poco de funcionalidad
Ejecutamos este código y vemos como la salida por consola es

Esto es una pequeña prueba que nos dice que nuestra calculadora funciona. Hacer las
pruebas manualmente tiene unos inconvenientes. Si cambiamos el código a lo siguiente
Podríamos no percatarnos de ese fallo porque quizas lo tenemos junto a muchas pruebas,
por lo que probar las cosas manualmente no es la mejor práctica.

Para ello podríamos asegurarnos mediante el siguiente código

Las ventajas de JUnit son.

1. Es un programa tan sumamente probado, que se considera altamente fiable


2. Se integra bien con los IDE’s
Primera prueba JUnit
Para crear una prueba unitaria le damos click derecho al proyecto, New/JUnit Test Case

Y le damos a OK cuando nos pida agregar la librería de JUnit al build path.


Ahora nos mostrará una clase llamada CalculadoraTest con una serie de imports hechos y
con el método llamado test() , que tiene una anotación (@Test), que lo que hace es marcar
al método como una prueba, de esta forma JUnit podrá reconocer automáticamente
métodos que sean pruebas.
Cualquier método public void que lleve la anotación @Test, será reconocido por JUnit como
prueba unitaria.

Vamos a ejecutar esta prueba unitaria. Click derecho a la clase CalculadoraTest/Run


As/JUnit Test.
Veremos como en el IDE aparece una nueva pestaña llamada JUnit que nos va a mostrar
los distintos fallos que ha encontrado con nuestra prueba unitaria.
Este fallo se debe a que estamos haciendo una llamada al método fail(). Si llamamos al
método fácil(), la prueba fallará. Además, se puede observar como nos indica que el fallo se
comete en la línea 11, la línea del método fail().

Ahora vamos a rehacer el código de la clase CalculadoraTest para realizar las pruebas
unitarias.

Ahora le tendremos que decir a JUnit que pruebe si las variables ​resultado ​y ​esperado s​ on
iguales. Para eso, JUnit me ofrece una serie de funciones que empiezan por “assert”,
llamaremos al assertEquals (el long, ya que se castea bien a entero).
En excepted le pondre el nombre de la variable que contiene el valor esperado (expected) y
en actual le pondré el valor del resultado obtenido(variable resultado)

Hacemos lo mismo para el método testResta()


Ahora corremos la prueba

Nos dice que las pruebas están correctas.


Si hubiésemos cometido algún error, por ejemplo haberme equivocado en la clase
Calculadora con los operadores
JUnit se había dado cuenta y nos devolverá dos errores

Esto nos va a venir bien porque podemos tener pruebas hechas y si por ejemplo
cambiamos código parcialmente de vez en cuando, nos podemos dar cuenta que algo ha
fallado.

Before y After
Son dos anotaciones que nos permiten ejecutar código antes y después dentro de una
determinada prueba. Para ello vamos a introducir una serie de cambios en nuestra
calculadora.
Hemos añadido un método constructor y 5 métodos donde todos ellos van a devolver el
valor de ans. Ans será interpretado como ese botón de una calculadora que guarda el último
valor. Por último, hemos añadido un método que nos va a poner ans a 0.

Ahora podemos crear pruebas unitarias para probar este código.


La anotación @Before sirve para ejecutar código antes de que se ejecute la prueba como
tal, es decir, cada sección de código que contenga la anotación @Test.
En este caso, vamos a crear un objeto de la clase Calculadora cada vez que se ejecute la
prueba
La anotación @After se va a ejecutar justo después de acabar una prueba. En este caso
vamos a querer que se reinicie el valor de la variable ans a 0, para ello hemos creado el
método llamado clear.
Si ejecutamos el test, comprobamos que lo ha hecho bien. Por un lado se ejecuta el before
cada vez que iniciamos un test, y ese test finaliza con un after.

Asserts
Todos los assertions están en la clase Assert (​public class Assert extends java.lang.Object)​
Esta clase ofrece una serie de métodos assertions, útiles para escribir tests. Solo los
assertions fallidos son grabados.
Algunos de los métodos de la clase Assert más importantes son los siguientes

1. void assertEquals(boolean expected, boolean actual)

Comprueba que dos objetos/primitivos son iguales

2. void assertTrue(boolean condition)

Comprueba que la condición sea True

3. void assertFalse(boolean condition)

Comprueba que la condición sea False

4. void assertNotNull(Object object)

Comprueba que un objeto no es null

5. void assertNull(Object object)

Comprueba que un objeto es null

6. void assertSame(object1, object2)

Comprueba si dos referencias objeto apuntan al mismo objeto

7. void assertNotSame(object1, object2)

Comprueba si dos referencias objeto no apuntan al mismo objeto

8. void assertArrayEquals(expectedArray, resultArray);

Comprueba si dos arrays son iguales.

Ejemplo
Vamos a usar algunos de los métodos mencionados anteriormente en un ejemplo.
Crearemos una clase java llamada TestRunner
Expected y Timeout
La anotación @Test tiene por característica que se le puede pasar un parametro, estos
pueden ser expected y timeout.

expected

Expected es un parámetro que puede usarse para indicar que un método se espera que
tiene una determinada excepción. Así conseguimos que una prueba unitaria falle en el caso
de que no se lance una excepción que se supone debería lanzarse.

Volvemos al ejemplo de la calculadora. En la clase calculadora, vamos a crear un método


que se llame div (dividir)

Ahora en la clase CalculadoraTest, vamos a hacer una prueba

Si corremos esta prueba, comprobaremos que no da ningún error.

¿Pero qué ocurre si hacemos una división de un número entre 0? Que su resultado es
infinito y nos devolverá un error.
Por lo tanto, deberíamos capturar ese error.

Ahora vamos al test, y lo dejamos como estaba antes, con la división entre un número
distinto de 0.

Pero imaginemos que yo quiero hacer una división entre 0. Quiero comprobar que cuando
divido entre 0 se genera un error. Tendremos que diseñar la prueba de la siguiente forma.

Comprobamos que no nos devuelve ningun error.


Sin embargo, si tenemos el caso en que no se divide por 0.

Se va a mostrar la excepción.

Esto es así porque se esperaba una excepción (ArithmeticException)

timeout

Sirve para hacer que una prueba falle, si una prueba se alarga en el tiempo más de lo
normal.
Por lo tanto, detendrá la ejecución si una función tarda “x” tiempo en ejecutarse.

Ejemplo. Tenemos un método que tiene una operación que debe ser óptima.

Si mi algoritmo tarda 2 segundos en ejecutarse deberá lanzar una excepción.


Para ello podemos crear una prueba donde diga que no puede tardar más de 100
milisegundos en ejecutarse.

La prueba se va a detener automáticamente en el caso en que tarde más de 100


milisegundos, entonces devolverá un error.

BeforeClass y AfterClass
Son dos anotaciones que se comportan como @Before y @After, pero que tienen la
particularidad de que se van a ejecutar una sola vez.
@BeforeClass se va a ejecutar antes de cualquier prueba unitaria que se ejecute dentro de
la clase
@AfterClass se va a ejecutar después de cualquier otra prueba que se haya ejecutado

Ejemplo. Siguiendo con nuestra calculadora, podríamos crear un BeforeClass que nos cree
la calculadora y un before que llame al método clear, de este modo la calculadora solo se
inicializa una única vez, no obstante se va a resetear antes de cada prueba para
asegurarnos de que se queda limpia y a la prueba unitaria (test) no le entra nada, es decir,
comienza limpio, no le entran ejecuciones anteriores.

Procedamos al cambio en el código.


Nota importante. Los métodos BeforeClass y AfterClass deben ser estáticos.

Lo que hemos hecho es crear un método estático llamado beforeClass() con la anotación
@BeforeClass que va a crear una instancia de la clase Calculadora, mientras que el método
before() lo que va a hacer ahora es llamar al método clear() para que cuando comience la
prueba, esta empiece limpia.

Por otro lado, crearemos un método estático llamado afterClass() con su anotación
@AfterClass que simplemente va a imprimir por pantalla un mensaje para que veamos que
solo se ejecuta una única vez. Además, al método after() le vamos a borrar la línea de
código en la que llama al método clear(), ya que no va a hacer falta.

Ahora lo ejecutamos (para que nos funcione hay que eliminar el @Test que teníamos con
timeout llamado testAlgoritmoOptimo).
En la ejecución vemos como todo va bien y en la consola se imprime 1 vez beforeClass y
afterClass.

Con el afterClass() lo que haremos sera que todos los recursos que se hayan cargado en el
before(), los podamos limpiar

Pruebas parametrizadas
Es una forma cómoda para ejecutar pruebas unitarias en las que lo que queremos es
comprobar que para varios valores obtenemos varios resultados.

Imaginemos que queremos comprobar varios casos de la función testSum(). Ahora mismo
tenemos la prueba de sumar 3+2, y queremos comprobar que un número positivo por otro
positivo da como resultado un número positivo, positivo por negativo da negativo, etc, es
decir, voy a tener varios grupos de datos que tengo que probar. Entonces, en vez de estar
utilizando esta prueba varias veces…
...cambiando los valores, puedo utilizar parámetros para darle a JUnit la prueba y los datos
y que JUnit se encargue.

Vamos a crear una clase vacía llamada CalculadoraParametroTest

Vamos a crear un constructor donde le vamos a pasar 3 parámetros (a,b,expected) y vamos


a crear un método llamado testAdd donde va a comprobar el resultado de una suma pasada
por parámetro.

Pero, ¿quien llama a este constructor?.


El propio JUnit. Para ello usamos una anotación llamada @RunWith, que cuando se utiliza
en la prueba unitaria, le dice a JUnit que ejecute eso con un runner particular, que se llama
Parameterized.class, que necesita un método public static que devuelve un objeto de tipo
Iterable que además sea de tipo array Object y tenga un nombre, por ejemplo getData y
debe devolver algo (return). Este método tiene que tener una anotación llamada
@Parameters. Lo que ocurrirá es que cuando se ejecute esa prueba con ese
runner(Parameterized), va a buscar el método que tenga la anotación @Parameters y que
sea compatible (método estático que devuelva un Iterable de arrays de objetos).
El Iterable es un ArrayList que va a contener arrays de objeto, que tendrán tantas
posiciones como parámetros tenga el constructor.
Ahora completamos el código

Si lo ejecutamos vemos como no da ningún error.

Con esto lo que conseguimos es que a partir de varios parámetros de entrada, podemos
correr de forma mas rapida, muchas más pruebas.

Test Suite
¿Cómo podemos correr una serie de pruebas de forma controlada y en orden?

En el ejemplo de la calculadora, teníamos creadas dos pruebas (CalculadoraParametroTest


y CalculadoraTest).
Le podemos pedir a Eclipse que nos ejecute las pruebas de todo el proyecto.

Y se correrán las pruebas de todas las clases de la forma que crea conveniente
A veces me interesa decirle a JUnit que se corran las clases de forma seguida porque
tienen que ver una con la otra.

Con el asistente de Eclipse se podrá crear un JUnit test suite de forma muy sencilla.
Ejecutamos la clase como si fuera una prueba más.
Se ejecutaran simultáneamente todas las pruebas en el orden en el que se le haya
especificado.

En resumen, el Test Suite se utiliza para agrupar unos cuantos casos de prueba de
unidades y ejecutarlos juntos. En JUnit, tanto las anotaciones @RunWith como @Suite se
utilizan para ejecutar los suite tests.

También podría gustarte