Constructor de pruebas automatizadas
Objetivo: pruebas que fallen solo cuando el producto está roto y que te cuenten por qué de un vistazo.
Antes de escribir código
- Encuentra la configuración existente:
playwright.config.*,pytest.ini/pyproject.toml, fixtures, helpers, page objects, datos de prueba. Extiende lo que ya existe. No añadas un segundo framework. - Elige el caso fuente. Si no hay ninguno, escribe primero el caso (pasos y resultado esperado) en la descripción de la prueba, luego el código.
- Decide la capa. Usa la capa más barata que aún detecte el error:
| Lo que quieres probar | Capa |
|---|---|
| Regla de negocio, validación, permisos | Prueba de API |
| Un usuario puede completar un flujo en la UI real | Una prueba E2E por flujo |
| Renderizado de un componente en muchos estados | Prueba de componente, si el proyecto las tiene |
| Los datos realmente cambiaron | Verificación de API o DB después del paso de UI |
Si el proyecto no tiene framework aún, empieza con Playwright Test para web y API, y pytest + requests para un servicio Python. Mantén el primer commit pequeño: configuración, un fixture, una prueba que pase, un trabajo de CI.
Localizadores
Preferir, en este orden:
getByRole(role, { name }), que también es una comprobación de accesibilidad.getByLabel,getByPlaceholder,getByTextpara texto estático.getByTestIdcuando el marcado no es semántico. Pide a los desarrolladores que añadandata-testiden lugar de usar rutas CSS.
Nunca uses XPath por índice, nombres de clase autogenerados o nth() sin una razón en un comentario.
Esperas
- No uses
waitForTimeoutnisleep. Espera un estado:await expect(locator).toBeVisible(),page.waitForResponse(url), o un sondeo sobre la API (expect.poll). - Las aserciones en Playwright reintentan. Usa
expect(locator)en lugar de leer texto y compararlo. - Si algo es lento por diseño (correo electrónico, cola), sondea con un timeout y un mensaje claro.
Datos de prueba y estado
- Crea lo que la prueba necesita a través de la API en un fixture, y límpialo después.
- Datos únicos por ejecución: añade un sufijo con una marca de tiempo o
test.info().workerIndex. - Inicia sesión una vez por rol con
storageState, no a través de la UI en cada prueba. - Nunca dependas del orden entre pruebas. Cada prueba debe pasar sola con
--grep.
Estructura
tests/
api/ comprobaciones rápidas de reglas y permisos
e2e/ flujos de usuario, pocos e importantes
fixtures/ autenticación, constructores de datos, cliente API
pages/ objetos de página solo cuando una página es usada por 3+ pruebas
Nombra las pruebas según el comportamiento: viewer cannot delete a project, no test_delete_3. Un comportamiento por prueba. Varias líneas expect están bien cuando describen ese único comportamiento.
Ejemplos en examples/: un flujo de UI con configuración de API, una prueba de permiso de API y una versión con pytest.
Terceros y efectos secundarios
Simula pasarelas de pago, correo electrónico, analíticas y mapas con page.route o un doble de prueba, a menos que la prueba trate sobre esa integración. Marca las pruebas de integración real con una etiqueta (@integration) para que CI pueda ejecutarlas por separado.
Des-flakeo de una prueba
- Reproduce:
npx playwright test <archivo> --repeat-each=20 --workers=4. - Abre el trace (
--trace on) de una ejecución fallida y encuentra el primer paso que difiere de una ejecución exitosa. - Causas habituales: una espera fija, un localizador que coincide con dos elementos, datos compartidos entre workers, animación, una solicitud que termina después de la aserción.
- Corrige la causa. Los reintentos en CI son una red de seguridad, no una solución. Nunca marques una prueba como omitida sin un enlace al ticket en el motivo de la omisión.
Definición de terminado
- La prueba pasa sola y en la suite completa, tres ejecuciones seguidas.
- La viste fallar: rompe la aserción o el estado de la aplicación una vez y comprueba que el mensaje de fallo tenga sentido.
- Sin secretos en el código. Las credenciales provienen de variables de entorno.
- El nombre de la prueba, el ID del caso (en una anotación o etiqueta) y el resultado esperado son legibles en el informe.
Informa con: archivos modificados, cómo ejecutarlos, qué cubren las pruebas y cualquier cosa que no hayas podido automatizar y por qué.