Un TDD (Test Driven Development) es una técnica de desarrollo software en la que primero pensamos en las pruebas que vamos a realizar y luego aplicar técnicas de refactorizamos para tener un código limpio.
Para elaborar estas pruebas lo que realizas primero son las pruebas unitarias que vamos a realizar y a continuación, en base a estas pruebas, realizamos la implementación de nuestro código. Después aplicamos la refactorización a nuestro código para tener una implementación lo mas limpia posible.
Vamos a realizar un ejemplo concreto para ver como aplicamos esta técnica
Supongamos que tenemos una aplicación donde estamos implementando la gestión de nuestro carrito de la compra. En nuestro carrito de la compra vamos a poder insertar cualquier articulo, y por cada articulo que nosotros añadamos se deberá actualizar el importe total. Tendremos en cuenta que si introducimos un elemento que ya se encuentra en nuestro carrito lo que realizaremos es un incremento de las unidades.
Partimos de las siguientes clases:
La clase Item que nos va a servir para almacenar los distintos elementos del carrito
class Item {
private String _nombre;
private Decimal _pUnidad;
private int _ctdad;
public String Nombre
{
get { return _nombre; }
set { _nombre = value; }
}
public Decimal PrecioUnidad
{
get { return _pUnidad; }
set { _pUnidad = value; }
}
public int Ctdad
{
get { return _ctdad; }
set { _ctdad = value; }
}
public Item()
{
Nombre = «»;
Ctdad = 0;
PrecioUnidad = 0;
}
public Item(String _n, int ctdad, Decimal precio)
{
Nombre = _n;
Ctdad = ctdad;
PrecioUnidad = precio;
}
}
Y la clase Carrito para gestionar los elementos que vamos añadiendo al carrito:
class Carrito {
private List<Item> carrito;
private Decimal _precTotal;
public Carrito(){
carrito = new List<Item>();
_precTotal = 0;
}
}
Si seguimos las normas del TDD primero vamos a diseñar las pruebas unitarias para los distintos requisitos que vamos a cumplir:
1.- Comprobar que el importe total es de 0 cuando no tenemos ningún elemento en la cesta.
La prueba unitaria que nosotros tendremos que realizar es la siguiente:
[TestMethod] public void CestaCompraVacia() { // Comprobamos Carrito c = new Carrito(); Assert.AreEqual(0, c.ItemsCarrito); // Comprobamos que hay cero elementos Assert.AreEqual(true, c.carritoVacio); // Comprobamos que el precio es 0 }
Ahora en nuestro código dentro de nuestra clase que gestiona el carrito completaremos su código con los siguientes propiedades:
public bool carritoVacio { get { return carrito.Count == 0; } }
public int ItemsCarrito
{
get { return carrito.Count; }
}
2.- Comprobamos que cuando insertamos un elemento se actualiza el precio total y el número de artículos
En este caso la prueba unitaria a realizar seria la siguiente:
public void Añadir1ItemCesta() { // Comprobamos Carrito c = new Carrito(); c.AddItem(new Item("CD's Virgenes",1,5)); Assert.AreEqual(5, c.PrecTotal); Assert.AreEqual(1, c.ItemsCarrito); }
Como el método de ItemsCarrito ya lo tenemos implementando como resultado de la prueba anterior lo único que tenemos que realizar es la propiedad para obtener el precio total
public Decimal PrecTotal { get { return _precTotal; } set { _precTotal = value; } }
y el método para añadir elementos al carrito:
public void AddItem(Item it) { _precTotal += it.PrecioUnidad * it.Ctdad; carrito.Add(it); }
3.- Comprobamos que cuando insertamos varios elementos se actualiza el precio total y el número de artículos teniendo en cuenta que podemos incluir elementos repetidos.
[TestMethod] public void AñadirVariosItemCesta() { // Comprobamos Carrito c = new Carrito(); c.AddItem(new Item("CD's Virgenes", 1, 5)); c.AddItem(new Item("CD's Virgenes", 1, 5)); c.AddItem(new Item("CD's Virgenes", 1, 5)); c.AddItem(new Item("DVD's Virgenes", 1, 10)); Assert.AreEqual(25, c.PrecTotal); Assert.AreEqual(2, c.ItemsCarrito); }
Si observamos, aparentemente podemos ejecutar la prueba para ya que tenemos todos los métodos y propiedades a utilizar correctamente. Al ejecutar la prueba veremos que esta prueba no la supera ya que cada item que hemos añadido los considera como un objeto nuevo. Por lo que tendremos que modificar el método AddItem para que compruebe si el item existe y en caso de que existe modificar la cantidad almacenada.
Para ello vamos a incorporar un método de busqueda de productos y modifcaremos el método AddItem de la siguiente forma:
private Item estaItem(String nombre) { foreach (Item it in carrito){ if (it.Nombre == nombre) return it; } return null; }
public void AddItem(Item it)
{
Item encontrado = estaItem(it.Nombre);
if (encontrado!=null)
{
encontrado.Ctdad += it.Ctdad;
}
else
{
carrito.Add(it);
}
_precTotal += it.PrecioUnidad * it.Ctdad;
}
Podemos observar que con esta técnica de desarrollo tenemos un control mas seguro sobre el cumplimiento de los requisitos que si primero desarrollamos y luego realizamos las pruebas.
Buena entrada Pablo.
Esta técnica es de las mejores para conseguir un software testado y de calidad, aunque tiene una curva costosa pero una vez que te metes no concibes otra manera de hacer las cosas 😀
Os dejo un libro gratuito para quien quiera indagar mas en el tema http://www.dirigidoportests.com/el-libro
Gracias Angel por tu felicitación y tu aporte.
Le echare un vistazo y veremos se este post inicia una serie de post sobre los TDD’s