Desarrollo Orientado a Pruebas (TDD) en React paso a paso

Clase 6 de 20Curso de React Testing Library

Resumen

¿Qué es el Test Driven Development (TDD)?

El Test Driven Development (TDD) es una metodología de desarrollo de software que cambia el orden tradicional de la creación de componentes. En lugar de comenzar desarrollando los componentes del software, TDD comienza con la escritura de pruebas. Esta estrategia garantiza que, cuando llegue el momento de refactorizar, existan pruebas que aseguren que las modificaciones no introduzcan errores.

¿Cómo funciona el ciclo TDD?

El ciclo del Test Driven Development pasa por tres etapas claras:

  1. Red (Rojo): En este paso, se crean las pruebas iniciales. Dado que el componente aún no existe, estas pruebas deben fallar.
  2. Green (Verde): Se desarrolla el componente para pasar las pruebas previamente configuradas.
  3. Refactor: Esta fase permite mejorar y optimizar el código con la seguridad de que las pruebas protegerán el sistema contra errores inesperados.

Es importante notar que esta metodología brilla en software ya bien definido, donde los casos de uso son claros. No es tan efectiva en software en fases experimentales o de constante cambio.

¿Cómo implementar TDD?

Creando pruebas iniciales

  1. Crea una carpeta para el componente, por ejemplo, contador.

  2. Dentro, inicia un archivo de pruebas, contador.test.tsx.

  3. Configura los imports clave de vitest, tales como describe, it y expect.

  4. Define los casos de prueba principales:

    • El contador debe mostrar inicialmente el valor "0".
    • Al hacer clic en un botón, el contador debe aumentar a "1".

Aquí se simula la renderización del componente (aunque todavía no existe) y se asegura el comportamiento esperado mediante testing library/react.

import { describe, it, expect } from "vitest";
import { render, screen, fireEvent } from "@testing-library/react";
import { Contador } from './Contador';

describe("Contador", () => {
  it("debería mostrar el valor inicial", () => {
    render(<Contador />);
    const contador = screen.getByText("Contador: 0");
    expect(contador).toBeInTheDocument();
  });
  
  it("debería incrementar el contador", async () => {
    render(<Contador />);
    const boton = screen.getByText("Incrementar");
    fireEvent.click(boton);
    const contador = screen.getByText("Contador: 1");
    expect(contador).toBeInTheDocument();
  });
});

Desarrollo del componente

  1. Crea o modifica el componente contador.tsx.
  2. Define su estado inicial y el comportamiento esperado:
import { useState } from 'react';

export const Contador = () => {
  const [contador, setContador] = useState(0);
  
  const handleIncrementar = () => setContador(contador + 1);

  return (
    <div>
      <p>Contador: {contador}</p>
      <button onClick={handleIncrementar}>Incrementar</button>
    </div>
  );
};

Refactorización con confianza

Una vez que las pruebas pasan exitosamente, puedes refactorizar el código con la seguridad de que las pruebas protegerán tu sistema contra la introducción de errores.

¿Por qué implementar TDD?

  • Calidad de Código: Proporciona una fuerte base de pruebas que permite cambios sin miedo a romper funcionalidades existentes.
  • Feedback Rápido: Informa de inmediato si un cambio introduce un error.
  • Diseño Eficiente: Fomenta la escritura de tests claros y concisos, lo que se traduce en código más limpio y entendible.

Reto propuesto

Crea un nuevo componente utilizando TDD. Algunas ideas son:

  • Un "todo list" que muestre elementos cuando se agreguen.
  • Un temporizador que cambie al estado "pausado" cuando se detenga.

La práctica constante de TDD no solo fortalece tus habilidades, sino que te prepara para crear sistemas robustos y seguras. ¡Anímate a compartir tus logros!