You are on page 1of 5

Diseño de Clases Java Guiado por Pruebas

Jorge Luis Palacio Pineda


XP Support BoK

1. Introducción

El TDD (Test Driven Development o Desarrollo Guiado por Pruebas) es


una [Bec08] aproximación evolutiva donde desarrollas primero las pruebas y
posteriormente el modulo o clase que realizara las funciones que estan bajo
prueba.
Por medio de esta proximación podemos asegurarnos de que el código que
estamos creando se adapta a las funciones esperadas y que además estas fun-
cionalidades existen aún cuando re realicen procesos de refactoring al código.
Keith Ray [Ray] plantea un modelo de pruebas que aproximadamente cubre
los siguientes pasos:
1. Crear una prueba.
2. Ejecutar las pruebas.
3. En caso de error hacer un pequeño cambio.
4. Volver a ejecutar las pruebas.
5. Si existen errores volver dos pasos atras.
6. Si no existen errores cerrar el caso de prueba.
Por medio de estos pasos podemos entonces generar un proceso de desarrollo
que esta basado en validación y no en vericación, lo que puede acelerar los
procesos de desarrollo.
Además de lo anterior, el seguimiento del control de calidad se da de una
manera más uida, por lo que podemos llegar, al realizar las pruebas en etapas
iniciales del proceso, a reducir los costos del proceso de desarrollo [Mur].

2. Descripción del Ejemplo

Desarrollar un componente simple que implemente las funciones básicas de


un cajero bancario: dépositos, retiros, consultas de saldo y estados de cuenta,
además de apertura y cierre de cuentas. Las funcionalidades deberan ser lo más
transparentes posibles al exterior.

1
3. Descripción de Historias de Usuario

1. Apertura de Cuenta: Una persona llega a la ventanilla del cajero, pro-


porciona sus datos personales, se le pide un déposito de apertura y un
monto de aseguranza de la cuenta. Se registran los datos de la persona en
el sistema (nombre, apellidos), la información de la nueva cuenta (numero
de cuenta, monto de apertura y movimiento inicial).
2. Cierre de Cuenta: Cuando una persona va a cerrar su cuenta debe pre-
sentar su identicación, se imprime un estado de cuenta con los movimien-
tos del ultimo mes natural, se realiza un corte del monto que aún existe
en la cuenta y se le entrega el monto al cliente.
3. Estado de Cuenta: El usuario llega con el cajero y proporciona su nom-
bre de usuario y su NIP, en base a estos datos el sistema recupera los
movimientos del mes natural en curso y los presenta al cliente.
4. Déposito: El usuario llega con el cajero y proporciona su nombre de
usuario y su NIP, se solicita realizar el déposito y se pide la suma a de-
positar, se agrega el monto a la cuenta.
Por cuestiones de tiempo vamos a limitarnos a las historias de usuario antes
mencionadas, hay que notar que el formato de las mismas no es el apropieado
y solamente se explican para poder entender el problema. Asumimos el uso del
lenguaje Java [Mic] y de la librería de pruebas JUnit[JUn].

4. Proceso de Desarrollo Basado en Prueba

Primeramente necesitamos decidir un poco de la lógica detras de la apli-


cación, para esto vamos a denir primordialmente la interfaz externa de la clase
de cuenta bancaria. Esto, tomando un modelo de BEAN podemos generarlo
como sigue:
public class Cuenta {
public String getPersona();
public void setPersona(String persona);

public float getSaldo();

public String validaNIP(String NIP);


public void setNIP(String viejo, String nuevo);

public static Cuenta crear(String persona, String NIP, float monto);


public void depositar(String persona, String NIP, float monto);
public List<Movimiento> estadoDeCuenta(String persona, String NIP);
public void cierre(String persona, String NIP);
}

2
Una vez que creamos el esqueleto de la clase Cuenta 1 podemos comenzar
con el diseño de la prueba. Comencemos con el caso de prueba de apertura:
public class TestCuenta extends TestCase {
public void testApertura() {
//Creamos una cueta con saldo de $4,000.00
Cuenta c = Cuenta.crear("JLPP", "12345", 4000.0);
//Verificamos que el proceso de creación sea correcto
assertEquals(c.getMonto(), 4000.0, delta);
}
}

Una vez que hemos creado el caso de prueba lo ejecutamos, obviamente la


ejecución del mismo fallara, para que funcione necesitamos tener el código para
generar la cuenta en la clase cuenta. Esto es trivial.
class Cuenta {
private String persona; //Agregamos un getter y un setter
private String NIP = "";
private float saldo = 0.0f; //Solo generamos getter

public static Cuenta crear(String persona, String NIP, float saldo) {


Cuenta c = new Cuenta();
c.persona = persona;
c.NIP = NIP;
c.saldo = saldo;

return c;
}

public float getSaldo() { return saldo; }


public String getPersona() { return persona; }
public void setPersona(String persona) {
this.persona = persona;
}
}

Una vez realizado el cambio pequeño volvemos a correr la prueba anterior-


mente creada. El resultado cumple entonces con nuestras expectativas y el fun-
cionamiento es tal como lo esperamos. En este punto podriamos haber denido
el resto de las pruebas o bien crearlas sobre la marcha. Comencemos por crear
la prueba para el déposito.
public void testDeposito() {
Cuenta c = Cuenta.crear("JLPP", "12345", 4000.0);
1 Necesitamos crear más códgio para completar las clases necesarias.

3
assertEquals(c.getMonto(), 4000.0, delta);

//Déposito inválido, el usuario no corresponde


c.depositar("JLPX", "12345", 500.0);
assertEquals(c.getMonto(), 4000.0, delta);
//Déposito inválido, el NIP es incorrecto
c.depositar("JLPP", "54321", 500.0);
assertEquals(c.getMonto(), 4000.0, delta);

//Déposito correcto
c.depositar("JLPP", "12345", 500.0);
assertEquals(c.getMonto(), 4500.0, delta);
}

Notese que en este caso estamos probando tanto los casos válidos como aque-
llos que consideramos incorrectos, para asegurar que el funcionamiento obtenido
sea el adecuado. Realizamos un pequeño cambio a la clase:
public void depositar(String persona, String NIP, float monto) {
this.monto += monto;
}

Después de realizar las pruebas estas fallaran en el primer assert del método
testDeposito, puesto que el déposito se realiza de manera correcta, no importa
el nombre de la persona y el NIP. Procedemos a realizar otro cambio:
public void depositar(String persona, String NIP, float monto) {
if(persona.compareTo(this.persona) != 0)
return;
this.monto += monto;
}

Esto pasará el error al segundo assert, el proceso de cambio y prueba se


realiza hasta que todos los casos de prueba se realizen y ejecuten de manera
completa.

5. Conclusiones y Notas

Por medio de este proceso de prueba, cambio, prueba; podemos realizar un


software que cumple por lo menos con una funcionalidad completa, aunque esto
no garantiza una aplicación libre de errores.

Referencias

[Bec08] Kent Beck. Test Driven Development: By Example . Addison-Wesley


Professional, Noviembre 2008.

4
[JUn] JUnit. Junit web site. Web Site. http://www.junit.org/.
[Mic] Sun Microsystems. Java web site. Web Site. http://java.sun.com/.
[Mur] Craig Murphy. Improving application quali-
ty using test-driven development (tdd). Article.
http://www.methodsandtools.com/archive/archive.php?id=20.
[Ray] Keith Ray. Keith ray's blog. Blog.
http://homepage.mac.com/keithray/blog/index.html.

You might also like