ConstructiCat Logo
CodeBust.
Browse section ▾

Ignored Test.

Una prueba que está confirmada en la base de código pero que nunca se ejecuta porque se ha omitido, desactivado o comentado, dando la apariencia de cobertura sin verificar nada en realidad.

##Signs and Symptoms

Una prueba existe en la suite pero tiene su ejecución impedida de forma permanente. Sigue contando como una "prueba" en el fichero, pero no aporta ninguna verificación. Vigila los marcadores de skip/ignore, los bloques con prefijo x, los cuerpos vacíos y el código de prueba enterrado en comentarios, a menudo acompañados de una excusa vaga como "flaky" o "fix later".

// modificadores skip/disabled: nunca se ejecutan
describe.skip('checkout flow', () => { /* ... */ });
it.skip('applies the discount', () => { /* ... */ });
test.todo('handles expired coupons');

// con prefijo x (jasmine/jest/mocha): mismo efecto
xit('rejects negative amounts', () => { /* ... */ });
xdescribe('payments', () => { /* ... */ });

// prueba comentada: invisible para el runner Y para el reporter
// it('retries on 503', async () => {
//   await expect(client.fetch()).resolves.toBeOk();
// });
// JUnit: @Ignore / @Disabled con un motivo poco riguroso
@Ignore("disabled for now as this test is too flaky")
@Test public void peerPriority() { /* ... */ }

Señales reveladoras en el informe de pruebas: un recuento de "skipped"/"pending" distinto de cero que nadie mira, suites que han encogido en silencio con el tiempo y omisiones sin incidencia vinculada ni caducidad. Los return condicionales al principio de una prueba (if (process.platform === 'win32') return;) son una variante más astuta que oculta por completo la omisión a los contadores de omisiones.

##Reasons for the Problem

Por qué ocurre

  • Una prueba empezó a fallar (una regresión real, una dependencia temporal inestable, un cambio de entorno o de versión) y omitirla fue la forma más rápida de conseguir una build verde o desbloquear un merge.
  • Una prueba se escribió antes que la implementación (test.todo/xit como marcador de posición) y nunca se retomó.
  • Las migraciones (nuevo framework, runtime o API) rompieron la prueba y se aparcó "temporalmente".
  • La omisión iba a durar una tarde; sin recordatorio, caducidad ni incidencia de seguimiento, se vuelve permanente.

Por qué es perjudicial

  • Falsa confianza. Una prueba omitida parece cobertura en el fichero y en el diff del PR, pero no ejercita nada. El camino de código que decía proteger queda ahora desprotegido, y todo el mundo da por hecho que es seguro.
  • Putrefacción (bit rot). Una prueba ignorada nunca se compila (en algunos lenguajes), nunca se refactoriza y nunca se actualiza. Cuanto más tiempo permanece, más se aleja de la realidad, hasta que reactivarla cuesta más que reescribirla.
  • Regresiones ocultas. El error o el comportamiento inestable que motivó la omisión sigue ahí: simplemente se ha silenciado. Omitir trata el síntoma (una barra roja) en lugar de la enfermedad.
  • Ruido y erosión. Los recuentos permanentes de "omitidas" enseñan al equipo a ignorar el informe de pruebas, lo que deja que se cuelen nuevas omisiones sin que nadie las note. El código de prueba muerto y comentado también añade carga de lectura y mantenimiento sin ningún beneficio.

##Treatment

Trata cada prueba ignorada como una decisión que debe tomarse ahora, no aplazarse indefinidamente.

  1. Clasifica cada omisión. Para cada prueba desactivada/comentada/todo, decide: arreglarla, eliminarla o ponerla en cuarentena con una caducidad y una incidencia de seguimiento. "Dejarla omitida para siempre" no es una opción.
  2. Arréglala y reactívala si el comportamiento sigue importando. Si la prueba es inestable, corrige la inestabilidad (controla el tiempo, la aleatoriedad, la asincronía y el estado compartido) en lugar de omitirla.
  3. Elimínala si la funcionalidad ya no existe o la prueba está obsoleta. Una prueba eliminada es honesta; una omitida miente. El control de versiones la recuerda por si alguna vez la necesitas de vuelta, así que nunca comentes una prueba en lugar de eliminarla.
  4. Si debes omitir temporalmente, hazlo de forma visible y acotada en el tiempo: incluye siempre un motivo y un enlace de seguimiento, y prefiere un mecanismo que aparezca en los informes y falle una vez pasado el plazo, para que la omisión no pueda pudrirse.
  5. Detén la hemorragia con lint/CI. Activa una regla de "no disabled tests" para que las nuevas omisiones se detecten en la revisión, y trata el recuento de omisiones existente como un backlog que reducir hasta cero.
// antes: silenciosa, permanente, sin seguimiento
it.skip('refunds the full amount on cancel', async () => {
  await expect(refund(order)).resolves.toEqual({ amount: 100 });
});

// después: arreglada y ejecutándose de nuevo (causa raíz: total en coma flotante)
it('refunds the full amount on cancel', async () => {
  await expect(refund(order)).resolves.toEqual({ amount: 100 });
});

// solución intermedia aceptable: visible, atribuida y con caducidad
it.skip('refunds the full amount on cancel — flaky clock, see JIRA-1234 (remove by 2026-07-01)', async () => {
  /* ... */
});
// antes
@Ignore("too flaky")
@Test public void peerPriority() { ... }

// después: corrige la dependencia temporal y reactívala, o elimínala si está obsoleta
@Test public void peerPriority() { ... }

##Detected by