sábado, 15 de enero de 2011

Desarrollo de Software dirigido por Pruebas: árboles binarios (Parte 2)

Te encuentras en la segunda parte de la serie "Desarrollo de Software dirigido por Pruebas":
  1. Diseño de las pruebas
  2. Implementación
  3. Refactoring
  4. Conclusiones y código
En el post anterior, definí el procedimiento de Desarrollo dirigido por Pruebas, también expuse su importancia y comencé a aplicar esta técnica en la implementación de tres tipos de árbol binario: árbol binario simlple, árbol AVL y Red-Black. En este post, mostraré con mayor detalle la organización de este proyecto así como el resultado de correr las pruebas elaboradas anteriormente.

Utilizando Netbeans implementé una clase abstracta llamada BinaryTree que servirá de base para crear las clases SimpleBinaryTree, AVLTree y RedBlackTree. Adicionalmente, implementé una clase llamada TreeNode, que se encarga de crear objetos tipo nodo, los cuales forman parte de la estructura de los objetos tipo árbol binario.

El siguiente diagrama de UML muestra la estructura del proyecto y las relaciones existentes entre las clases.


En este diagrama se muestran los métodos más importantes para cada clase. Nuevamente me gustaría reafirmar que hasta este punto, los cuerpos de dichos métodos están vacíos. En Netbeans, la organización del proyecto es la siguiente:


¿Qué sucede si corremos las pruebas en este punto? Dado que aún no existe la implementación de los métodos a probar, al correr las pruebas obtendremos mensajes de error, tal y como se muestra a continuación.



En este momento ya sabemos qué es lo que la implementación de los métodos debe arrojar y también, a través de la elaboración de las pruebas, pudimos visualizar más claramente la manera en que realizaremos dicha implementación. Pues bien, ahora sí podemos comenzar a codificar los cuerpos de los métodos.

Probablemente, al terminar de codificar algunas pruebas fallen, pero los mensajes que aparecen en la ventana de Test Results pueden ayudarnos a observar en dónde se está presentando la conduca anómala y su corrección puede ser más rápida.

Además, si cada prueba está enfocada a evaluar un aspecto en particular de la implementación, nos pueden ayudar a aislar errores. Por ejemplo, en el caso del borrado de nodos diseñé pruebas para los tres casos: el borrado de una hoja, el borrado de un nodo con un hijo y el borrado de un nodo con dos hijos. Al correr las pruebas después de la implementación del borrado, se presentó un error en la prueba del borrado de un nodo con dos hijos. Esto me ayudó a enfocarme en corregir la parte del código que se encarga de este caso. Cuando todas las pruebas pasen, podemos tener mayor seguridad de que la implementación es correcta:


La clase que implementé hasta ahora es SimpleBinaryTree. En los siguientes posts, realizaré el mismo procedimiento (pruebas primero, implementación después) para las clases AVLTree y RedBlackTree.

No hay comentarios:

Publicar un comentario