Por qué TDD no es solo otra metodología de moda, sino tu nueva capa de superhéroe
Imagina: escribes código como un artista — pincelada tras pincelada, línea tras línea. Estás seguro de que todo es genial. Pero pasa una hora, ejecutas la aplicación y falla con un error que te tomaría medio día encontrar. ¿Te suena familiar?
Ahora imagina otro escenario. Primero escribes una prueba que fallará con certeza. Luego, el código mínimo para que la prueba pase. Y solo entonces, refactorizas, mejoras, pero ya con la conciencia tranquila. Esto es el desarrollo guiado por pruebas (TDD), y en Kotlin se convierte en un verdadero placer.
En este artículo no daremos aburridas lecciones. Tomaremos un ejemplo real, recorreremos las tres etapas de TDD (Red — Green — Refactor) y mostraremos cómo escribir código confiable sin miedo ni reproches. ¿Listo? ¡Allá vamos!
TDD: tres letras que cambiarán tu código
TDD (Test-Driven Development) no es solo una técnica, es una filosofía. La esencia es simple: primero la prueba, luego el código. ¿Suena descabellado? A primera vista, sí. En la práctica, ahorra horas de depuración.
El ciclo del desarrollo guiado por pruebas
- Red — escribimos una prueba que no pasa (debe fallar).
- Green — escribimos el código mínimo para que la prueba pase.
- Refactor — mejoramos el código sin cambiar su comportamiento.
Y así, en círculo, en pequeños pasos. Cada paso es la certeza de que no has roto nada. En Kotlin, con su sintaxis concisa y seguridad nula, TDD se vuelve aún más agradable.
Herramientas: qué necesitas para TDD en Kotlin
Antes de sumergirnos en el código, preparemos el arsenal. Para las pruebas unitarias en Kotlin necesitarás:
- JUnit 5 — el estándar de facto para pruebas unitarias.
- MockK — biblioteca para mocks, creada específicamente para Kotlin (sin más problemas con null y companion object).
- Gradle o Maven — para gestionar dependencias.
Agrega en build.gradle.kts:
dependencies { testImplementation("org.junit.jupiter:junit-jupiter:5.10.0") testImplementation("io.mockk:mockk:1.13.8")}Listo. Ahora puedes escribir código del que no te avergüences mostrar a tus colegas.
Escribimos el primer ciclo TDD: una calculadora con ambiciones
Empezamos con lo clásico: una calculadora. Pero no una simple, sino con soporte para operaciones con cadenas. Tarea: la función calculate recibe una cadena como "2 + 3" y devuelve 5.
Paso 1: Red — escribimos una prueba que falla
Creamos la clase de prueba:
import org.junit.jupiter.api.Testimport org.junit.jupiter.api.Assertions.assertEquals
class CalculatorTest {
@Test fun `debería sumar dos números`() { val calculator = StringCalculator() val result = calculator.calculate("2 + 3") assertEquals(5, result) }}Ejecutamos — la prueba falla porque la clase StringCalculator aún no existe. Señal roja: todo va según el plan.
Paso 2: Green — código mínimo para que pase
Escribimos exactamente lo necesario para que la prueba pase. Sin lujos arquitectónicos:
class StringCalculator { fun calculate(expression: String): Int { val parts = expression.split(" + ") return parts[0].toInt() + parts[1].toInt() }}Ahora la prueba está en verde. ¡Hurra! Pero el código aún es feo — solo está diseñado para sumar dos números.
Paso 3: Refactor — hacemos el código bonito
Refactorizamos, pero sin cambiar el comportamiento. Agregamos soporte para diferentes operaciones, extraemos la lógica en funciones separadas:
class StringCalculator { fun calculate(expression: String): Int { val (a, op, b) =