Ejemplo de framework de automatización de pruebas: construye una suite escalable

  1. Inicio
  2. Blog
  3. Automatización de pruebas

Automatización de pruebas

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.

Por Stack QuoraActualizado el 29 oct 20269 min de lectura
Ejemplo de framework de automatización de pruebas con una estructura de carpetas escalable

Ideas clave

  • 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 @smoke para 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

Trabaja con Stack Quora

¿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.