Ejemplo Junit. Probando la calculadora a partir de pruebas unitarias.

Por descargarpseint / hace 5 meses / 0 Comentarios ».

Hoy pretendo que comiences a experimentar con las pruebas unitarias a través de un ejemplo Junit. Para ello comenzaré explicándote que son y el porqué de su existencias e inmediatamente después nos pondremos manos a la obra a definir un conjunto de pruebas, declararlas utilizando Eclipse, ejecutándolas y aprendiendo a interpretar los resultados gracias a la vista Junit. Finalmente te propondré un conjunto de ejercicios adicionales para que puedas consolidar tu conocimiento respecto a esta tecnología java.

Si aún no tienes instalado JUnit en tu eclipse entonces te recomiendo que primero leas el artículo donde te explico como hacerlo.

¿Qué es una prueba unitaria?. Test Case.

Según la wikipedia una prueba unitaria es

Una prueba unitaria es una forma de probar el correcto funcionamiento de un módulo de código. Esto sirve para asegurar que cada uno de los módulos funcione correctamente por separado.

Para probar la calculadora vamos a definir pruebas unitarias que verifiquen que la operación sumar funciona correctamente bajo diferentes escenarios de ejecución. Por ejemplo, vamos a hacer las siguientes cuatro pruebas.

Prueba1: 0+0 = 0

Prueba2: 1+0 = 1

Prueba3: -1+1 = 0

Prueba4: 500 +2147483647 = número negativo

En los unit test que hemos definido arriba estamos comprobando situaciones que todos entendemos que debe cumplir la operación sumar.

  1. La suma de dos números con valor cero debe dar como resultado cero.
  2. La suma de cualquier número con el cero dará como resultado ese número.
  3. La suma de un número mas su inverso dará como resultado cero.
  4. La suma de un número que está en el límite de los números soportados por los enteros dará como resultado un desbordamiento del rango.

¿Qué propiedades debe cumplir una prueba unitaria?.

  • Automatizable
  • Completas:
  • Repetibles o Reutilizables:
  • Independientes:
  • Profesionales:

Aquí lo que debes ir comprendiendo es que una prueba unitaria es un trozo de código cuya finalidad es ahorrar trabajo al programador (se programa una vez y permite probar un trozo de código muchas veces). Además es interesante que pruebe el mayor número de líneas de código (un test prueba una línea de código cuando la ejecución del test fuerza la ejecución de dicha línea de código bajo unas condiciones determinadas).

La prueba tiene que ser independiente, primero, para poder ejecutarse muchas veces (ahorrando tiempo al desarrollador o testeador) y, segundo, para que ni altere el resultado de otras pruebas ni tampoco la ejecución de otros test case puedan alterar el resultado del mismo.

Hasta aquí toda las teoría y conceptos que considero que necesitas saber antes de comenzar a experimentar con las pruebas unitarias. Para ello vas a programar un ejemplo Junit completo dentro de eclipse. ¿Estás preparado?. Vamos allá

Creando un Junit Test Case desde Eclipse.

El primer paso va a ser abrir el asistente de creación de pruebas unitarias. Para ello vas a seguir los pasos descritos en la imagen de abajo (Previamente tendrás que haber creado un paquete dentro de la carpeta test. Puedes consultar el artículo donde explico como se puede crear un paquete en eclipse si tienes alguna duda).

Al hacer click sobre la opción JUnit Test Case te aparecerá el asistente de creación

El asistente es muy parecido a los de creación de una clase o definición de un interfaz. Por ahora solo vas a especificar nombre de la clase. El resto de opciones las dejaremos deshabilitadas. Si pulsas en Finish verás que eclipse construye el siguiente código básico con algunas opciones fundamentales para que un test pueda ejecutarse.

package com.programarenjava.tuturiales.calculadora.implementaciones;

import static org.junit.Assert.*;

import org.junit.Test;

public class SumarDosEnterosTest {

        @Test

        public void test() {

               fail("Not yet implemented");

        }

¿Qué cosas ha hecho eclipse por nosotros?.

Introducir el código donde se especifica el paquete, dentro del cual, se está definiendo el test (te recuerdo que en el fondo un test es una clase java y como cualquier clase pertenece a un paquete (palabra package), se define como una clase (palabra class) e importa todas aquellas clases y paquetes que vaya a utilizar durante su definición y ejecución).

Ha importado una clase (org.junit.Test) y también el método estático fail() definido dentro de la clase org.junit.Assert. Si te fijas en el método que ha definido test() verás que justo encima tiene una anotación (@Test). La función de la misma es decirle al Framework Junit que ese método debe tratarlo con un test unitario y por lo tanto deberá evaluar si la condición especificada dentro de el se cumple o no.

fail() sirve para hacer fallar el test. ¿Qué sentido podría tener esto?. Como puedes ver en este ejemplo Junit, sirve para indicarnos que la prueba falla debido a que aún no ha sido programada.

Programando el caso de prueba 0 + 0 = 0.

Lo primero que vas a hacer es definir un nuevo método llamado testCeroMasCeroIgualACero.

A continuación te muestro el código resultante:

        @Test

        public void testCeroMasCeroIgualACero(){

               Number sumar;

               boolean sumaIgualACero;

               sumar = calculadora.sumar(0, 0);

               sumaIgualACero = (sumar.intValue() == 0);

               Assert.assertTrue(sumaIgualACero);

        }

Lo primero que puedes ver es que hemos etiquetado el método como un test unitario gracias a la anotación @Test. Después hemos declarado dos variables que nos van a servir para almacenar el resultando de la suma (sumar) y para comprobar si se cumple la condición a validar o no (sumaIgualACero).

sumar = calculadora.sumar(0, 0);

Esta sentencia es donde el test está poniendo a prueba a la calculadora de enteros. Si el código que estamos probando es correcto entonces el resultado almacenado en la variable sumar debería ser cero.

sumaIgualACero = (sumar.intValue() == 0);

En la línea anterior hemos descrito la comparación, que en caso de ser cierta, cumplirá el criterio La suma de dos números con valor cero debe dar como resultado cero.

Assert.assertTrue(sumaIgualACero);

Finalmente, nos apoyamos en el método estático assertTrue cuya función es la de comprobar que se cumple la prueba. La clase Assert contiene un conjunto variado de métodos que puedes consultar en su API.

Antes de pasar a ejecutar el test quiero explicarte como hemos declarado e instanciado la variable calculadora.

public class SumarDosEnterosTest {

        private Calculadora calculadora = new CalculadoraDeIntegers();

Como puedes ver, hemos declarado la variable calculadora con ámbito de clase. De esta forma podremos utilizar esta variable en los diferentes test que definamos. Además, te recuerdo que la finalidad de esta clase test case es la de probar las implementaciones de la calculadora de enteros.

Ejecutando y comprendiendo el resultado de la Junit Test Case.

El primer paso va a consistir en ejecutar el test. Para ello tendrás que situarte sobre la clase y pulsando el botón derecho verás un menú. En el tendrás que seleccionar Run as -> JUnit Test. Al hacerlo se ejecutará la prueba y aparecerá la vista Junit indicándote como ha ido la ejecución.

 ¿Cómo puedes interpretar los resultados?.

Lo primero que debes mirar es el color de a barra lateral. En este caso es verde y eso está indicando que la batería de pruebas (ejecuciones de métodos etiquetados con la anotación @Test) se ha ejecutado satisfactoriamente.

También nos ofrece información sobre el tiempo que ha tardado en ejecutarse. En el ejemplo estamos hablando de 49 milisegundos. Quizás ahora te parezca poco relevante pero imagina por un momento un gran proyecto, con muchas clases y métodos donde tuviéramos que lanzar 10000 pruebas unitarias.

Sin duda, el coste de diseñar y programar las pruebas se cubre con creces cuando estos test se van ejecutanto una y otra vez. Este conjunto de pruebas terminan formando parte del pool de pruebas de regresión, cuya función es la de garantizar que las funcionalidades que ya funcionaban siguen haciéndolo cuando se introducen cambios.

Los elementos (Runs, Errors y Failures) nos indican numéricamente como han ido las pruebas. Finalmente, en el centro de la vista, puedes ver un listado con los métodos que se han ejecutado y el estado de la ejecución.

Quiero proponerte que programes las pruebas 2 y 3. Sin embargo, el caso 500 +2147483647 = número negativo es un poco especial y vas a programarlo para que la ejecución del mismo sea errónea.

        @Test

        public void testQuinientosMasNumeroGrandeEsMayorQueCero(){

               Number sumar;

               boolean sumaMayorQueCero;

               sumar = calculadora.sumar(500, 2147483647);

               sumaMayorQueCero = (sumar.intValue()>0);

               Assert.assertTrue(sumaMayorQueCero);

        }

Teóricamente la suma de dos números positivos debería dar como resultado otro número, mayor que los dos primeros, y positivo. Bien, en esta prueba queremos comprobar que se cumple la segunda condición, sin embargo, al ejecutar nuevamente el test obtenemos el siguiente resultado.

Esta vez se han ejecutado dos pruebas, la primera ha funcionado correctamente, sin embargo, la segunda ha producido un failure. ¿Por qué está ocurriendo esto?. Se trata de un desbordamiento de rango, algo que ya vimos en la programación de la calculadora con tipos primitivos. La solución está a tu alcance y tiene que ver con el uso de la clase Long. ¿Serías capaz de hacer que el test funcione sin cambiar nada de la prueba testQuinientosMasNumeroGrandeEsMayorQueCero?.

Hasta aquí el capitulo de ejemplo Junit, dentro del curso Tutorial en Java Programando una calculadora paso a paso. Espero que ahora tengas una mayor comprensión de lo que son los tes unitarios y del concepto de probar bloques de código para garantizar su correcto funcionamiento con el paso del tiempo y la evolución del mismo. Te he propuesto algunos ejercicios que me gustaría que intentaras resolver. En el próximo artículo te ofreceré la solución a estas cuestiones y además te introduciré el concepto de rafactorización de código.

Ver: descargar pseint portable gratis

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *