---
title: "Prueba verbosa"
type: "test-smell"
slug: "verbose-test"
url: "http://localhost:3000/es/test-smells/verbose-test.md"
category: "Olores oscuros"
description: "Una prueba que usa mucho más código del necesario para plantear su escenario, sepultando la única relación de causa y efecto que verifica bajo código repetitivo de preparación, datos irrelevantes y aserciones campo por campo."
---
# Prueba verbosa

> Una prueba que usa mucho más código del necesario para plantear su escenario, sepultando la única relación de causa y efecto que verifica bajo código repetitivo de preparación, datos irrelevantes y aserciones campo por campo.

## Signs and Symptoms

No puedes saber de un vistazo qué demuestra una prueba, aunque no esté ocurriendo nada complicado: la intención queda ahogada en el volumen. Indicios habituales:

* El método de prueba es **largo** (el catálogo de Test Smells usa un umbral aproximado de **\>30 líneas**) o se extiende más allá de una pantalla.
* Un gran bloque `arrange` construye objetos campo por campo, gran parte de ellos irrelevantes para el comportamiento bajo prueba.
* Muchos **literales codificados a mano** sin un vínculo evidente entre las entradas y las salidas afirmadas.
* El resultado se comprueba con un **montón de aserciones de un solo campo** en lugar de una única comparación significativa.
* Al leer las aserciones, no resulta fácil relacionar qué entrada provocó qué valor esperado.

```js
test('places an order for a returning customer', () => {
  const address = new Address();
  address.street = '123 Main St';
  address.city = 'Springfield';
  address.zip = '00000';                          // irrelevante para esta prueba
  address.country = 'US';

  const customer = new Customer();
  customer.id = 42;
  customer.firstName = 'Ada';
  customer.lastName = 'Lovelace';
  customer.email = 'ada@example.com';
  customer.address = address;
  customer.createdAt = new Date('2020-01-01');     // ruido

  const product = new Product();
  product.sku = 'SKU-1';
  product.name = 'Widget';
  product.price = 9.99;

  const cart = new Cart();
  cart.add(product, 2);

  const order = orderService.placeOrder(customer, cart);

  expect(order.status).toBe('CONFIRMED');          // las únicas líneas que importan
  expect(order.lineItems.length).toBe(1);
  expect(order.lineItems[0].sku).toBe('SKU-1');
  expect(order.lineItems[0].quantity).toBe(2);
  expect(order.total).toBe(19.98);
  expect(order.customerId).toBe(42);
});

```

Alrededor de 25 líneas de construcción custodian una aserción de dos líneas sobre totales y estado.

## Reasons for the Problem

**Por qué ocurre**

* _Construcción en línea con campos obligatorios._ Construir objetos reales mediante constructores/setters te obliga a aportar datos que a la prueba no le importan, solo para que el código compile y se ejecute. Meszaros señala que el nivel de detalle necesario para hacer ejecutable una prueba puede volverla «tan verbosa que resulta difícil de entender».
* _Crecimiento por copiar y pegar._ Una prueba empieza siendo pequeña y luego cada nuevo escenario se crea copiando el anterior y ajustando un valor, así que el ruido se acumula.
* _Sin ayudantes de construcción compartidos._ Sin métodos de creación (Creation Methods), constructores (builders) ni fixtures, cada prueba vuelve a declarar el grafo de objetos completo.
* _Datos codificados a mano y verificación campo por campo._ Escribir literales por todas partes y hacer aserciones sobre cada propiedad parece «exhaustivo», pero multiplica el número de líneas.

**Por qué resulta perjudicial**

* _Legibilidad._ La Prueba verbosa es una variante de la **Prueba oscura**: el catálogo incluso indica «Prueba oscura» como su alias. Quien lee no puede ver la relación de causa y efecto entre el fixture y el resultado, que es el sentido mismo de una prueba basada en ejemplos.
* _Mantenibilidad._ Una prueba de más de 30 líneas tiende a cargar con «varias responsabilidades», de modo que un pequeño cambio en producción se propaga a muchas líneas a lo largo de muchas pruebas. La preparación en línea masiva también genera duplicación.
* _Falsa confianza._ Las pruebas largas y ruidosas ocultan errores a plena vista: un literal incorrecto o una aserción mal colocada pasan fácilmente desapercibidos, y la verbosidad hace que los revisores lean por encima. El volumen aparenta rigor sin demostrar nada más.
* _Fiabilidad._ Cuanto más estado irrelevante fija una prueba, más probable es que se rompa por motivos ajenos a su intención (sobreespecificación), produciendo fallos frágiles y de baja señal.

## Treatment

Saca el ruido fuera del cuerpo de la prueba para que solo queden visibles las variables que determinan el comportamiento. Acciones concretas (todas de _xUnit Test Patterns_):

1. **Extrae métodos de creación (Creation Methods) / usa un constructor (builder).** Sustituye la construcción de objetos en línea por un ayudante con un nombre evocador que aporte valores por defecto razonables; pásale solo los valores que de verdad le importan a la prueba (método de creación parametrizado). Esto elimina tanto el código repetitivo como la información irrelevante.
2. **Asigna por defecto los datos irrelevantes dentro del ayudante**, señalando que «estos valores no afectan al resultado».
3. **Sustituye las comprobaciones campo por campo por un objeto esperado (Expected Object)** (`toEqual`/`toMatchObject`) o una **aserción personalizada / método de verificación** que nombre el concepto que se está verificando.
4. **Verifica un solo comportamiento por prueba.** Si una sola prueba es larga porque ejercita varios resultados (una Prueba ansiosa, Eager Test), divídela.
5. **Parametriza** las pruebas verbosas casi idénticas con `test.each` / `it.each` en lugar de copiar y pegar.

```js
// antes  — véase Indicios y síntomas (≈30 líneas de preparación + 6 aserciones)

// después
test('confirms the order and charges line-item total', () => {
  const customer = aCustomer();                          // Método de creación, valores por defecto
  const cart = aCartWith(aProduct({ price: 9.99 }), 2);  // solo la entrada relevante

  const order = orderService.placeOrder(customer, cart);

  expect(order).toMatchObject({                          // Objeto esperado, no campo por campo
    status: 'CONFIRMED',
    total: 19.98,
  });
});

```

El escenario ahora se lee en segundos: un cliente compra dos unidades de un producto de 9,99 $ → el pedido se confirma con un total de 19,98 $. Los ayudantes (`aCustomer`, `aProduct`, `aCartWith`) son utilidades compartidas y probadas, así que el ruido vive en un solo lugar en lugar de en cada prueba.

Salvaguarda: limita en tu linter la longitud de las funciones de prueba y el número de aserciones (véanse los detectores) para que las pruebas no vuelvan a crecer en silencio hasta convertirse en Pruebas verbosas.

## Detected by

- **eslint** `max-lines-per-function` — Impone un número máximo de líneas por función: señala los cuerpos de prueba que superan el límite configurado, la medida central de una Prueba verbosa. (https://eslint.org/docs/latest/rules/max-lines-per-function)
- **eslint** `max-statements` — Impone un número máximo de sentencias en un bloque de función: limita cuánto puede hacer una única prueba (un callback de función o de flecha). (https://eslint.org/docs/latest/rules/max-statements)
- **sonar** `S138` — Las funciones no deberían tener demasiadas líneas de código: se aplica a las funciones de prueba; señala los métodos de prueba sobredimensionados y con múltiples responsabilidades (RSPEC-138). (https://rules.sonarsource.com/javascript/RSPEC-138/)
- **eslint-jest** `jest/max-expects` — Impone un número máximo de llamadas a expect() por prueba (5 por defecto): detecta la faceta de acumulación de aserciones de las pruebas verbosas/ansiosas. (https://github.com/jest-community/eslint-plugin-jest/blob/main/docs/rules/max-expects.md)
- **eslint-vitest** `vitest/max-expects` — Impone un número máximo de llamadas a expect() por prueba (5 por defecto): equivalente de Vitest a jest/max-expects. (https://github.com/vitest-dev/eslint-plugin-vitest/blob/main/docs/rules/max-expects.md)
