Usando la versión 4.4 de JUnit, me he dedicado a investigar lo que este framework puede hacer.
Resumidamente JUnit es una herramienta para realizar pruebas de nuestras clases Java.
Las clases que se crean extendiendo a junit.framework.TestCase serán el lugar donde probaremos nuestras ya creadas clases. No se tiene que modificar la clase que se prueba, y se dice que es una excelente práctica el ubicar nuestras clases de prueba (casos de prueba) en el mismo paquete en el que se encuentran las clases a las que probaremos, aunque algunos la ubican en un diferente paquete, ganando organización, pero perdiendo la posibilidad de utilizar los métodos protegidos por el ámbito de paquete.
Entonces, un caso de prueba, es una clase que tiene como función encontrar errores de otra, regularmente los casos de prueba se nombran con el nombre de la clase a probar y el sufijo Test. Así, para probar la clase ProveedorCafe.java, llamaremos a la clase: ProveedorCafeTest, no es una regla ni es necesario para hacer funcionar la prueba, pero si es una convención.
Un caso de prueba realizará todo el montón de comprobaciones sobre los métodos de la clase que se está probando. Realmente todo lo que podemos hacer es que comprobar que los métodos regresen el valor esperado después de una serie de instrucciones controladas, esto es, después de indicarle a un método que regrese la suma de dos números (2+2), que su resultado sea 4. Lo hacemos por medio de comprobaciones assertXxx, a las que llamamos expresiones de prueba. Por ejemplo:
assertEquals(sumar2Numeros(2,2),4);
Más adelante mostraremos la ubicación de está expresión de prueba en la clase, lo importante es comprender que la clase TestCase, de la cual extendemos y creamos nuestros casos de prueba, contiene una buena cantidad de expresiones de prueba, para verificar que un método regresa Verdadero o Falso, que dos objetos son o no iguales (recordar reescribir el método equals), etc.
No solo funciona con métodos, con cualquier expresión valida de Java.
Las expresiones se encontrarán en métodos que inician con el prefijo test y el nombre de un testtestAgregarDatos.Un ejemplo completo a continuación:
import junit.framework.TestCase;
public class RecetaTest extends TestCase {
public Receta rec;
public void setUp() {
rec=new Receta();
}
public void testCreation(){
rec.setName("Chocolate");
rec.setPrice(50);
rec.setAmtCoffee(6);
rec.setAmtMilk(4);
rec.setAmtSugar(2);
rec.setAmtChocolate(4);
System.out.println("Verificando entrada de datos validos");
assertEquals("Datos no iguales", rec.getPrice(),50);
assertEquals("Datos no iguales", rec.getAmtCoffee(),6);
assertEquals("Datos no iguales", rec.getAmtMilk(),4);
assertEquals("Datos no iguales", rec.getAmtChocolate(),4);
assertEquals("Datos no iguales", rec.getAmtSugar(),2);
}
public void tearDown(){
rec=null;
}
}
Un ejemplo donde solo hacemos uso de un tipo de expresión de prueba, pero observamos que tiene un mensaje. Este mensaje será el que se muestre si la expresión no es evaluada como se espera, en este caso, que ambos datos sean iguales. Se espera que clase receta sea creada con los valores que le damos y que no exista nada en esta secuencia de instrucciones que nos indique que no fue así.
Los métodos
setUp() y
tearDown() son como el constructor y destructores de la clase, serán siempre llamados para cada prueba de un método en un caso de prueba. Esto es, aquí podemos inicializar nuestros objetos y no repetir código (cada método testXXX reinicia las variables de instancia).
Eclipse trae ya integrada la compatibilidad con JUnit, bastará con correr el programa como UnitTest.
Si las pruebas son demasiadas y hay muchas clases para probar, pero en el futuro no las probaremos todas, existen las
TestSuite que son las clases encargadas de correr un conjunto de Casos de prueba, esto es meramente organizacional, pero nos permite organizar un conjunto de pruebas en un solo archivo java y mandar llamar a todas las pruebas, evitando hacerlo unitariamente.
import junit.framework.Test;
import junit.framework.TestSuite;
public class AllTests {
public static Test suite() {
TestSuite suite = new TestSuite("Mi Suite");
suite.addTestSuite(RecetaTest.class);
suite.addTestSuite(CafeTest.class);
suite.addTestSuite(InventarioTest.class);
return suite;
}
}
Tan simple como un contenedor de Casos de Prueba. Y este contenedor, tiene la capacidad de absorver a otros contenedores de casos de prueba y llamarlos a todos de una sola vuelta
y estos serán los encargados de verificar la clase.