No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Curso de React Testing Library

Curso de React Testing Library

Wilmer Javier Garzon Cabezas

Wilmer Javier Garzon Cabezas

Testing con Table Driven en React: Mejora Mantenibilidad y Cobertura

5/20
Recursos

¿Qué es el Table Driven Testing?

El Table Driven Testing es una técnica que mejora la eficiencia y organización de las pruebas unitarias. Esta metodología permite probar múltiples casos de uso con flujos similares, pero con resultados esperados distintos, utilizando un solo test. Este enfoque no solo optimiza tiempo y esfuerzo, sino que mejora la mantenibilidad y legibilidad del código. Aquí se destacan cuatro beneficios clave del Table Driven Testing:

  • Mantenibilidad: editar un array es más sencillo y eficiente que modificar cada caso de prueba individualmente en un archivo.

  • Legibilidad: centraliza la información en un solo lugar, facilitando la revisión y comprensión de las pruebas.

  • Eficiencia: un solo test ejecuta todos los casos de uso de un componente.

  • Cobertura: minimiza el riesgo de olvidar casos de prueba pequeños, asegurando una revisión completa de las posibles entradas y salidas.

¿Cómo implementar Table Driven Testing en tus proyectos?

Implementar el Table Driven Testing en un proyecto puede optimizar tus pruebas considerablemente. A través de un ejemplo práctico, como un componente calculadora que suma, resta, multiplica o divide dos números, se pueden ver las bondades de esta metodología.

Creación de un archivo de prueba

Primero, se debe crear un archivo de prueba para gestionar los tests. En este caso, se crea el archivo calculator.test.tsx e importan las funciones necesarias desde vitest, como describe, it, y expect.

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

Configuración de los casos de prueba

Aquí es donde comienza la magia del Table Driven Testing. Se crea un array que contendrá los distintos casos de prueba: useCasesTest. Este array incluye varios objetos con combinaciones diferentes de variables de entrada y el resultado esperado.

const useCasesTest = [
  { a: 1, b: 2, operation: "sumar", expected: 3 },
  { a: 3, b: 2, operation: "multiplicar", expected: 6 },
];

Configuración de la suite de pruebas

Se utiliza la función describe para definir la suite de pruebas y each de jest para iterar sobre los casos de prueba configurados.

describe("Calculator Component", () => {
  it.each(useCasesTest)(
    "debería retornar $expected cuando A es $a y B es $b y la operación es $operation",
    ({ a, b, operation, expected }) => {
      render();
      const result = screen.getByText(`Result: ${expected}`);
      expect(result).toBeInTheDocument();
    }
  );
});

Corrección y validación del test

Si algún test falla, analiza el error para corregir casos como el de la operación inválida. De esta forma, se garantiza que los tests cubren correctamente las funcionalidades del componente.

¿Cómo enfrentar retos avanzados y mejorar?

El Table Driven Testing es solo un inicio en la mejora continua del proceso de prueba de software. Te reto a que expandas tu array useCasesTest, añadiendo más casos, especialmente aquellos que puedan romper tus funciones, como divisiones por cero. Esto permite explorar escenarios inesperados y asegura la robustez del código.

Finalmente, el próximo paso natural es adentrarse en el Test Driven Development (TDD), que le da un enfoque revolucionario al desarrollo basado en la creación previa de las pruebas, lo que estaremos explorando próximamente.

¡Sigue adelante! Tu aprendizaje solo acaba de empezar y tu habilidad como desarrollador se fortalecerá con cada prueba bien estructurada y superada. 🚀

 

Aportes 4

Preguntas 0

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Test de la clase incluyendo la división entre cero: ```js import { describe, it, expect } from 'vitest'; import { render, screen } from '@testing-library/react'; import { Calculator } from './Calculator'; describe('<Calculator />', () => { const useCasesTest = [ { a : 2, b : 3, operation : 'add', expected : 5 }, { a : 5, b : 3, operation : 'subtract', expected : 2 }, { a : 2, b : 3, operation : 'multiply', expected : 6 }, { a : 6, b : 3, operation : 'divide', expected : 2 }, { a : 6, b : 0, operation : 'divide', expected : "Error" }, ]; it.each(useCasesTest)('renders calculator with %p expected $expected when $a and $b will be $operation', ({ a, b, operation, expected }) => { render(<Calculator a={a} b={b} operation={operation} />); const result = screen.getByText(`Result: ${expected}`); expect(result).toBeInTheDocument(); }); }); ```import { describe, it, expect } from 'vitest';import { render, screen } from '@testing-library/react';import { Calculator } from './Calculator'; describe('\<Calculator />', () => { const useCasesTest = \[ { a : 2, b : 3, operation : 'add', expected : 5 }, { a : 5, b : 3, operation : 'subtract', expected : 2 }, { a : 2, b : 3, operation : 'multiply', expected : 6 }, { a : 6, b : 3, operation : 'divide', expected : 2 }, { a : 6, b : 0, operation : 'divide', expected : "Error" }, ]; it.each(useCasesTest)('renders calculator with %p expected $expected when $a and $b will be $operation', ({ a, b, operation, expected }) => { render(*\<Calculator* a={a} b={b} operation={operation} */>*); const result = screen.getByText(`Result: ${expected}`); expect(result).toBeInTheDocument(); });});
La sintaxis con **placeholders** `$` en los strings de las descripciones como en `it.each` (o `test.each`) **es específica de Vitest y Jest**, porque estas bibliotecas tienen esta funcionalidad incorporada.
✅ Passed ```js ✓ src/components/experimental/Calulator.test.tsx (5 tests) 41ms ✓ <Calulator /> > Debería retornar 3 cuando 1 y 2 son 'add' ✓ <Calulator /> > Debería retornar 2 cuando 5 y 3 son 'subtract' ✓ <Calulator /> > Debería retornar 6 cuando 2 y 3 son 'multiply' ✓ <Calulator /> > Debería retornar 2 cuando 6 y 3 son 'divide' ✓ <Calulator /> > Debería retornar 'Error' cuando 6 y +0 son 'divide' ```
Dejo un ejemplo de la implementacion usando tipado. y regExp interface Case  {    a: number    b: number    operation : Operation    expected: string} describe("Calculator", () => {    const a = 1    const b = 10    const common = {a,b}     const useCases : Case\[]= \[        {...common, operation : "add", expected: "11" },        {...common, operation : "substract", expected: "-9" },        {...common, operation : "multiply", expected: "10" },        {...common, operation : "divide", expected: "0.1" },        {...common, b: 0, operation : "divide", expected: "Error" }, // dividir entre 0        {...common, operation : "anasbsy", expected: "Invalid operation"},    ]     it.each(useCases)(`Deberia retornar $expected cuando $a y $b son $operation`, (option) => {        render(\<Calculator {...option} />)            const reg = new RegExp(option.expected, "i")            const label = screen.getByText(reg)            expect(label).toBeInTheDocument()    })}) ```js interface Case { a: number b: number operation : Operation expected: string } describe("Calculator", () => { const a = 1 const b = 10 const common = {a,b} const useCases : Case[]= [ {...common, operation : "add", expected: "11" }, {...common, operation : "substract", expected: "-9" }, {...common, operation : "multiply", expected: "10" }, {...common, operation : "divide", expected: "0.1" }, {...common, b: 0, operation : "divide", expected: "Error" }, // dividir entre 0 {...common, operation : "anasbsy", expected: "Invalid operation"}, ] it.each(useCases)(`Deberia retornar $expected cuando $a y $b son $operation`, (option) => { render(<Calculator {...option} />) const reg = new RegExp(option.expected, "i") const label = screen.getByText(reg) expect(label).toBeInTheDocument() }) }) ```