Yeda AI Tips · #072

English

Nunca uses waitForTimeout — espera la red real

Elimina hoy mismo cada timeout fijo de tu suite de tests. Un waitForTimeout(5000) es una adivinanza: cuando la app responde en 300 ms desperdicia 4.7 segundos en cada ejecución, y cuando el CI está lento igual falla. Las esperas fijas son la única técnica que hace una suite más lenta y más frágil al mismo tiempo — y ambos problemas desaparecen en cuanto esperas la condición real en lugar del reloj.

Por qué una espera fija nunca puede estar bien

No existe un número correcto para un sleep. Si lo eliges corto, el test falla en un runner de CI cargado; si lo eliges largo, pagas la demora completa en cada ejecución verde. Multiplica un sleep de 5 segundos por 40 tests y 20 corridas de CI al día, y estás quemando más de una hora diaria de máquina en esperas que no verifican nada.

Los test runners modernos coinciden. La guía oficial de Playwright recomienda las aserciones web-first: "By using web first assertions Playwright will wait until the expected condition is met." Cypress lista "waiting for arbitrary time periods using cy.wait(Number)" como un anti-patrón explícito y recomienda "use route aliases or assertions to guard Cypress from proceeding until an explicit condition is met."

Qué esperar en su lugar

1. La respuesta de red. Si la UI está esperando un request, el test también debería:

// Playwright — wait for the exact request the click triggers
const responsePromise = page.waitForResponse(
  (res) => res.url().includes('/api/users') && res.status() === 200
);
await page.getByTestId('fetch-users').click();
await responsePromise;
// Cypress — alias the route, then wait on the alias
cy.intercept('GET', '/users').as('getUsers');
cy.get('[data-testid="fetch-users"]').click();
cy.wait('@getUsers');

2. El resultado visible. Las aserciones web-first vuelven a revisar el DOM "over and over, until the condition is met or until the timeout is reached" — con un timeout por defecto de 5 segundos en Playwright:

await expect(page.getByTestId('status')).toHaveText('Submitted');
await expect(page.getByRole('row')).toHaveCount(2);

Ambas continúan en el instante en que la condición se cumple. App rápida, test rápido; red lenta, test paciente. El mismo código.

Reglas prácticas

Escribiste un sleep porque…Reemplázalo con
Los datos siguen cargandowaitForResponse / cy.wait('@route') con alias
El elemento aún no apareceexpect(locator).toBeVisible() — reintenta solo
El texto no se actualizóexpect(locator).toHaveText(...)
Una animación está terminandoAsevera sobre el estado final, no la transición
"Solo necesita un momento"Aún no conoces la condición — encuéntrala primero

Las acciones de Playwright además auto-esperan por sí solas: click() ejecuta chequeos de accionabilidad (visible, habilitado, estable) antes de disparar, así que la mayoría de los sleeps previos a un click nunca fueron necesarios.

Trucos avanzados

Recursos

¿Desarrollas código asistido por IA? Yeda AI diseña, audita y entrega sistemas LLM de producción.

Habla con nosotros · Más tips · Read in English