/ insights

TDD - El mito y lo real

TDD es un estilo de desarrollo bastante práctico -así como pedido por las empresas-, pero muchas veces no es posible ser aplicado. Encuentra aquí un pequeño vistaso al ¿Por qué?

TDD (Test Driven Development)

Palabras más ó palabras menos, la idea detrás del TDD es comenzar desarrollando las pruebas unitarias para después ir a la implementación. Suena raro, ¿No?

Tomemos un ejemplo. Tenemos un requerimiento funcional (historia de usuario) que dice algo como: calcular el costo del envío en base al peso y distancia del envío, el costo será manejado siempre en el mismo currency

En algún punto caemos en cuenta que básicamente necesitamos un sólo método (al menos a alto nivel), pero en lugar de comenzar a definirlo en código para la implementación, lo haremos a nivel de la prueba:

public class MyServiceTest {
  public void testCalculateDeliveryCost() {
    long distance = 100; // <<== meters
    double weight = 10d; // <<== kilos
    double cost = myService.calculate(distance, weight);
    
    Asssert.isTrue(cost == THE_PRICE);
  }
}

Ahora bien, no importa en qué tecnología trabajes, sabes que después de escribir algo así, con la información que tenemos hasta ahora, TIENE QUE MARCAR ERROR, posiblemente declaraste la interface, pero en el mundo de TDD, tanto el servicio, como sus métodos, deberían crearse hasta que las pruebas estén completas. Y sinceramente al principio hace sentido cuando escuchas ¿Cómo osas implementar algo que no sabes cómo probar?, pero discutiremos este punto más adelante

Bien, entonces continuamos a crear la interface e implementar el método:

public interface MyService {

  /**
   * Calculates the cost of the delivery based on the distance it will be carried and the weight of the package.
   * @param distance - The distance from point A to B in meters.
   * @param weight - Package's weight in Kilos.
   * @return The price in currency X.
   */
  double calculate(long distance, double weight);
}

¿La interface no cubre el objetivo del TDD?

Ahora bien, decidí realizar este ejemplo en un lenguaje strongly typed como Java, precisamente por la opción de interfaces, y es que aquí comienzan algunas opiniones:

  • El objetivo de la interface es definir la estructura y comportamiento de la implementación. Si bien no lo estamos probando, lo estamos diseñando sin brincar a lanzar código, ¿no?

Y la respuesta es si y no, y antes de ponernos cuánticos aquí expliquemos. Si, la interface es para definir el diseño / estructura de la implementación, pero si no tienes desarrolladores tan experimentados, por ejemplo, un JR / Middle, o incluso un Senior / Arquitecto con muy poca información del requerimiento, la interface puede decir misa (puede lucir como sea) pero existe el riesgo de no ser correcto

Ventaja del TDD

Al definir las pruebas inicialmente, antes del código, te hace preguntarte sobre la naturaleza del requerimiento y cómo satisfacerlo, este es un punto que una interface no puede proporcionarte, ya que es un elemento muy abstracto y la prueba es más pragmático, más como un ejercicio mental de ayuda

Casos inalcanzables

Retomando el ejemplo, contábamos con la información mínima necesaria para comenzar a trabajar, sin embargo, no todos los proyectos son así:

  • Transición de una consultoría a otra
  • Mantenimiento / soporte bajo deadlines comprometidos
  • Poca información funcional
  • Desconocimiento de la implementación actual

Todos estos factores pueden colaborar para que el TDD parezca más como un estorbo, en lugar de una ayuda. Y ciertamente, personalmente creo que hay muchos escenarios en los cuales TDD no puede ser aplicado, he estado en proyectos en los cuales creen que TDD significa hacer pruebas unitarias para todo o tener un test coverage de X o Y porcentaje, y ese no es el objetivo principal. Aunque esas práticas traen muchas ventajas en cuanto a escalabilidad, no son parte de la idea inicial del TDD

Así que bien, no te sientas mal si no puedes hacer TDD en un 100% del código que escribes, mientras logres identificar en los casos que son de ayuda y lo utilices como herramienta de apoyo, en lugar de un check más en una lista interminable de habilidades necesarias para la industria, todo estará bien