Es una técnica de programación que emplea pruebas unitarias y refactorización de código.
El ciclo de vida de TDD comprende tres etapas
- Escribir una prueba que falle (rojo)
- Escribir una prueba que pase (verde)
- Refactorización, mejorar el código sin afectar su funcionamiento interno
Problema. Obtener el número de pulsaciones de una persona con 15 segundos de ejercitación.
Entrada: edad de la persona
Salida: número de pulsaciones
Restricciones o casos posibles:
- la edad no debe ser cero o un valor negativo,
- un valor flotante (ej. 4.5)
- o un carácter.
Fórmula. Num_pulsaciones = (220 – edad)/15
El primer paso es crear una prueba que falle, existen libros sobre TDD y Refactorización que indican la forma realizar los test, pero bien lo trataré de hacer según mi entendimiento.
PulsacionTest. Java
@Test
public void testObtenerPulsaciones() {
Pulsacion pulsacion = new Pulsacion();
System.out.println("obtenerPulsaciones: entero positivo");
int edad = 26;
double expResult = 12.0;
assertEquals(expResult, pulsacion.obtenerPulsaciones(edad), 0.0);
}
Obvio es que falle (no tengo que probar). Ahora el segundo paso es crear el código necesario (Pulsacion.java) para pasar la prueba.
//Código inicial
Pulsacion.java
public double obtenerPulsaciones(int edad){
return (220-edad)/15;
}
Listo pasa la primer prueba (valor entero no negativo). Ahora otro problema, es necesario realizar pruebas para los tres casos posibles (valor cero o negativo, valor flotante, o carácter).
Para ahorrar líneas de código defino “pulsación” como un atributo de la clase PulsacionTest.java para que sea accesible para los demás métodos.
He aquí el código aplicando TDD y un poco de Refactorización.
PulsacionTest. Java
Pulsacion pulsacion = new Pulsacion();
//para un valor entero no negativo
@Test
public void testObtenerPulsaciones() {
System.out.println("obtenerPulsaciones: entero positivo");
int edad = 26;
double expResult = 12.0;
assertEquals(expResult, pulsacion.obtenerPulsaciones(edad), 0.0);
}
// para un valor cero o negativo
@Test
public void testObtenerPulsacionesNegativoCero(){
System.out.println("obtenenerPulsaciones: cero o negativo");
int edad_neg=-26;
double expResult1=14.0;
assertEquals(expResult1, pulsacion.obtenerPulsaciones(edad_neg), 0.0);
}
// para un valor flotante
@Test
public void testObtenerPulsacionesReal(){
System.out.println("obtenenerPulsaciones: real");
double edad_real=26.0;
double expResult2=12.0;
assertEquals(expResult2, pulsacion.obtenerPulsaciones((int)edad_real), 0.0);
}
//para un carácter
@Test
public void testObtenerPulsacionesCaracter(){
System.out.println("obtenenerPulsaciones: caracter");
String edad_cad="26";
double expResult3=12.0;
assertEquals(expResult3, pulsacion.obtenerPulsaciones(Integer.parseInt(edad_cad)), 0.0);
}
En este método se podría agregar otro método que compruebe si la cadena introducida es numérica o no.
public bolean esNumerico (String cad){
try{
Integer.parseInt (cad);
return true;
}catch(NumberFormatException ex){
return false;}
}
//Código final
Pulsacion.java
public double obtenerPulsaciones(int edad){
if((int)edad<=0){
return (220-0)/15;
}
else if((int)edad>0){
return (220-(int)edad)/15;
}
else{
return (220-edad)/15;
}
}