viernes, 25 de noviembre de 2011

TDD… ejemplos básicos



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

  1. Escribir una prueba que falle (rojo)
  2. Escribir una prueba que pase (verde)
  3. 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:
  1. la edad no debe ser cero o un valor negativo,
  2. un valor flotante (ej. 4.5)
  3. 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;
}
}

No hay comentarios:

Publicar un comentario