diseño de clases java guiado por pruebas

5

Click here to load reader

Upload: juliocombativo

Post on 06-Jun-2015

5.171 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Diseño de Clases Java Guiado por Pruebas

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) esuna [Bec08] aproximación evolutiva donde desarrollas primero las pruebas yposteriormente el modulo o clase que realizara las funciones que estan bajoprueba.

Por medio de esta proximación podemos asegurarnos de que el código queestamos 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 cubrelos 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 desarrolloque esta basado en validación y no en veri�cación, lo que puede acelerar losprocesos de desarrollo.

Además de lo anterior, el seguimiento del control de calidad se da de unamanera más �uida, por lo que podemos llegar, al realizar las pruebas en etapasiniciales 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 deun 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ástransparentes posibles al exterior.

1

Page 2: Diseño de Clases Java Guiado por Pruebas

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 unmonto de aseguranza de la cuenta. Se registran los datos de la persona enel sistema (nombre, apellidos), la información de la nueva cuenta (numerode cuenta, monto de apertura y movimiento inicial).

2. Cierre de Cuenta: Cuando una persona va a cerrar su cuenta debe pre-sentar su identi�cación, se imprime un estado de cuenta con los movimien-tos del ultimo mes natural, se realiza un corte del monto que aún existeen 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 losmovimientos del mes natural en curso y los presenta al cliente.

4. Déposito: El usuario llega con el cajero y proporciona su nombre deusuario 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 antesmencionadas, hay que notar que el formato de las mismas no es el apropieadoy solamente se explican para poder entender el problema. Asumimos el uso dellenguaje 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 de�nir primordialmente la interfaz externa de la clasede cuenta bancaria. Esto, tomando un modelo de BEAN podemos generarlocomo 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

Page 3: Diseño de Clases Java Guiado por Pruebas

Una vez que creamos el esqueleto de la clase Cuenta 1 podemos comenzarcon 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 laejecución del mismo fallara, para que funcione necesitamos tener el código paragenerar 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 de�nidoel resto de las pruebas o bien crearlas sobre la marcha. Comencemos por crearla prueba para el déposito.

public void testDeposito() {

Cuenta c = Cuenta.crear("JLPP", "12345", 4000.0);

1Necesitamos crear más códgio para completar las clases necesarias.

3

Page 4: Diseño de Clases Java Guiado por Pruebas

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 obtenidosea 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étodotestDeposito, puesto que el déposito se realiza de manera correcta, no importael 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 serealiza hasta que todos los casos de prueba se realizen y ejecuten de maneracompleta.

5. Conclusiones y Notas

Por medio de este proceso de prueba, cambio, prueba; podemos realizar unsoftware que cumple por lo menos con una funcionalidad completa, aunque estono garantiza una aplicación libre de errores.

Referencias

[Bec08] Kent Beck. Test Driven Development: By Example. Addison-WesleyProfessional, Noviembre 2008.

4

Page 5: Diseño de Clases Java Guiado por Pruebas

[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.

5