Ejemplo de framework de automatización de pruebas: construye una suite escalable
La teoría es fácil. Ver una estructura real es mejor. Sigue este ejemplo de framework de automatización de pruebas y copia las partes que encajen con tu proyecto.
- Separa pruebas, page objects, datos y configuración.
- Pon cada localizador en un solo lugar.
- Usa fixtures para preparar y limpiar datos.
- Ejecuta la suite en CI y conserva los informes de los fallos.
Muchos equipos empiezan con unas pocas pruebas en un archivo. Funciona una semana. Después la suite crece, los localizadores se repiten y un pequeño cambio en la interfaz rompe veinte pruebas.
Un buen framework lo evita. A continuación tienes un ejemplo sencillo y honesto con Playwright y TypeScript. Las ideas sirven para cualquier herramienta, así que puedes adaptarlas a Selenium, Cypress u otro stack.
Qué vamos a construir
Vamos a automatizar una pequeña tienda online. La suite comprueba el inicio de sesión, la búsqueda y añadir al carrito. Queremos que sea fácil de leer, rápida de ejecutar y sencilla de ampliar cuando aparezcan nuevas páginas.
Paso 1: configura la estructura de carpetas
Una estructura clara es la mitad de la batalla. Esta funciona bien para proyectos pequeños y medianos:
shop-tests/
├─ tests/
│ ├─ auth/login.spec.ts
│ ├─ cart/add-to-cart.spec.ts
│ └─ search/search.spec.ts
├─ pages/
│ ├─ LoginPage.ts
│ ├─ ProductPage.ts
│ └─ CartPage.ts
├─ fixtures/
│ └─ test-fixtures.ts
├─ data/
│ └─ users.json
├─ utils/
│ └─ api-helpers.ts
├─ playwright.config.ts
└─ .env.example
- tests/ contiene los archivos de pruebas, agrupados por funcionalidad.
- pages/ contiene los page objects con localizadores y acciones.
- fixtures/ contiene la preparación compartida, como un usuario con sesión iniciada.
- data/ contiene los datos de prueba, nunca escritos a mano en las pruebas.
- utils/ contiene pequeñas utilidades, como llamar a la API para crear datos.
Paso 2: mantén la configuración y los datos fuera de las pruebas
Pon la URL base, los tiempos de espera y la lista de navegadores en un único archivo de configuración. Guarda los secretos en variables de entorno.
// playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
testDir: './tests',
fullyParallel: true,
retries: process.env.CI ? 1 : 0,
reporter: [['html'], ['list']],
use: {
baseURL: process.env.BASE_URL || 'https://staging.shop.example.com',
trace: 'retain-on-failure',
screenshot: 'only-on-failure',
},
});
Guarda los usuarios de prueba en un archivo JSON para poder cambiarlos sin tocar el código de las pruebas:
// data/users.json
{
"standard": { "email": "buyer@example.com", "password": "from-env" }
}
Paso 3: construye page objects
Un page object envuelve una página. Mantiene los localizadores y las acciones en un solo lugar. Cuando cambia la interfaz, editas un solo archivo.
// pages/LoginPage.ts
import { Page, expect } from '@playwright/test';
export class LoginPage {
constructor(private page: Page) {}
async open() {
await this.page.goto('/login');
}
async login(email: string, password: string) {
await this.page.getByLabel('Email').fill(email);
await this.page.getByLabel('Password').fill(password);
await this.page.getByRole('button', { name: 'Sign in' }).click();
}
async expectLoggedIn() {
await expect(this.page.getByText('My account')).toBeVisible();
}
}
Regla general: los page objects contienen acciones y localizadores. Las pruebas contienen las comprobaciones que explican la regla de negocio.
Paso 4: comparte la preparación con fixtures
Las fixtures dan a cada prueba los objetos que necesita, ya preparados. Esto elimina el copiar y pegar.
// fixtures/test-fixtures.ts
import { test as base } from '@playwright/test';
import { LoginPage } from '../pages/LoginPage';
import { CartPage } from '../pages/CartPage';
type Pages = { loginPage: LoginPage; cartPage: CartPage };
export const test = base.extend<Pages>({
loginPage: async ({ page }, use) => { await use(new LoginPage(page)); },
cartPage: async ({ page }, use) => { await use(new CartPage(page)); },
});
export { expect } from '@playwright/test';
Paso 5: escribe pruebas cortas y claras
// tests/cart/add-to-cart.spec.ts
import { test, expect } from '../../fixtures/test-fixtures';
test('el comprador puede añadir un producto al carrito', async ({ page, cartPage }) => {
await page.goto('/products/running-shoes');
await page.getByRole('button', { name: 'Add to cart' }).click();
await cartPage.open();
await expect(cartPage.itemNames()).toContainText(['Running shoes']);
});
La prueba se lee como una frase. Un nuevo compañero puede entenderla en segundos. Para más reglas sobre pruebas estables, lee nuestra guía de buenas prácticas de pruebas end-to-end.
Paso 6: añade informes útiles
Una prueba que falla debe decirte por qué. Activa capturas, vídeo o trazas solo para los fallos, para mantener el almacenamiento pequeño. El informe HTML integrado de Playwright es un buen comienzo. Más adelante puedes enviar los resultados a un panel o a un canal de chat.
Paso 7: ejecútalo en CI
Este es un trabajo sencillo de GitHub Actions que instala dependencias, ejecuta la suite y guarda el informe:
name: e2e
on: [pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 20 }
- run: npm ci
- run: npx playwright install --with-deps
- run: npx playwright test
- uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report
path: playwright-report/
¿Nuevo en los pipelines? Nuestra guía de GitHub Actions explica cada parte.
Cómo mantener el framework escalable
- Un localizador, un hogar. No repitas nunca un localizador entre pruebas.
- Pruebas pequeñas. Una prueba, un comportamiento.
- Pruebas independientes. Crea los datos que necesites mediante la API y límpialos después.
- Etiqueta tus pruebas. Usa etiquetas como
@smokepara ejecutar un subconjunto rápido en cada pull request. - Revisa a menudo. Elimina las pruebas muertas y arregla las inestables en cada sprint.
¿Aún eliges herramienta? Mira primero cómo elegir el mejor framework de automatización de pruebas.
Preguntas frecuentes
¿Qué es una buena estructura de framework de automatización de pruebas?
Separa tus pruebas, page objects, fixtures, datos y configuración en carpetas propias. Así cada archivo es pequeño y fácil de encontrar.
¿Necesito el modelo de page objects?
No es obligatorio, pero ayuda mucho cuando tienes más de un puñado de pruebas. Elimina los localizadores repetidos y hace que las actualizaciones sean sencillas.
¿Puedo usar esta estructura con Selenium o Cypress?
Sí. Las carpetas y las ideas son las mismas. Solo cambia la sintaxis dentro de los archivos.
¿Cuántas pruebas deben ejecutarse en cada pull request?
Ejecuta un pequeño conjunto de smoke en cada pull request y la suite completa al fusionar o por la noche. Así equilibras velocidad y seguridad.
Sigue aprendiendo
¿Necesitas ayuda con testing, WordPress o SEO?
Ayudamos a los equipos a lanzar mejor software y a hacer crecer sus sitios. Cuéntanos en qué trabajas y te sugeriremos un siguiente paso claro.
Más guías sobre testing, IA y desarrollo moderno
¿Te gustó este artículo? Elige otro tutorial y sigue aprendiendo.
Mejores herramientas de automatización de pruebas 2026: las favoritas de los equipos de QA
Compara las mejores herramientas de automatización de pruebas en 2026 para pruebas web, móviles y de API. Mira qué hace bien cada una, para quién es y cómo elegir sin perder semanas.
Leer artículo →Desarrollo de softwareBuenas prácticas de API REST 2026: construye servicios escalables
Aprende buenas prácticas de API REST para 2026: URL claras, códigos de estado correctos, versionado, paginación, seguridad y gestión de errores, con ejemplos sencillos que puedes usar hoy.
Leer artículo →Inteligencia artificialArquitectura MCP sin estado: novedades de MCP 2026
La especificación MCP 2026-07-28 elimina las sesiones y el handshake. Descubre cómo funciona MCP sin estado, qué se rompe, qué se vuelve más fácil de escalar y cómo migrar tu servidor.
Leer artículo →