Introducción

Las pruebas end-to-end tienen fama de ser lentas e inestables. Las herramientas basadas en Selenium corren en un proceso separado del navegador, lo que genera problemas de temporización y pruebas que fallan aleatoriamente incluso cuando la aplicación funciona correctamente. Cypress adopta un enfoque diferente: corre dentro del propio navegador, en el mismo event loop que la aplicación. Esto elimina toda una categoría de problemas de temporización y hace que las pruebas sean más rápidas de escribir y más fáciles de depurar.

¿Qué es Cypress?

Cypress es una herramienta de pruebas open-source construida para aplicaciones JavaScript modernas. Corre directamente en el navegador y funciona con React, Angular y Vue.js sin configuración adicional. Incluye un test runner gráfico que muestra exactamente lo que ocurrió en cada paso, además de un mecanismo de espera automática que elimina la necesidad de sleeps o waits explícitos en tus pruebas.

Características Principales de Cypress

  • Time Travel: Cypress toma snapshots mientras corren las pruebas. Pasa el cursor sobre cualquier comando en el log para ver el estado de la aplicación en ese momento.
  • Depurabilidad: mensajes de error legibles y stack traces claros. Los fallos describen lo que ocurrió, no solo qué aserción falló.
  • Espera Automática: Cypress espera a los elementos del DOM, las solicitudes de red y las animaciones antes de continuar. No necesitas dispersar cy.wait(1000) por tus pruebas.
  • Recargas en Tiempo Real: los archivos de prueba se recargan automáticamente al guardarlos.
  • Control de Tráfico de Red: intercepta y reemplaza solicitudes HTTP para probar estados de error y casos límite sin depender de un backend activo.

¿Por qué Usar Cypress?

Las pruebas inestables son peores que ninguna prueba: erosionan la confianza hasta que el equipo empieza a ignorar los fallos. El modelo in-process de Cypress elimina la mayoría de las race conditions que causan inestabilidad en otras herramientas. La GUI interactiva hace que depurar fallos sea rápido, ya que puedes ver exactamente cómo estaba la aplicación en el momento exacto en que falló la prueba.

Cómo Implementar Cypress

Instalación

Asegúrate de tener Node.js instalado y, a continuación, añade Cypress a tu proyecto:

npm install cypress --save-dev

O bien, usando yarn:

yarn add cypress --dev

Configuración Inicial

Abre Cypress por primera vez para generar las carpetas y archivos necesarios:

npx cypress open

Esto crea una carpeta cypress con:

  • fixtures/ para datos de prueba estáticos.
  • integration/ para archivos de prueba (specs).
  • plugins/ para extender o modificar el comportamiento de Cypress.
  • support/ para comandos personalizados reutilizables y configuración global.

Configuración

Personaliza los ajustes en cypress.json:

{
  "baseUrl": "http://localhost:3000",
  "viewportWidth": 1280,
  "viewportHeight": 720,
  "video": true
}

baseUrl es la URL donde corre tu aplicación. viewportWidth y viewportHeight definen las dimensiones del navegador. video habilita la grabación de las ejecuciones de prueba.

Creando un Sistema de Ejemplo

Configurando una Aplicación de Ejemplo

Crea una aplicación Todo básica usando React:

Paso 1: Crear una Nueva App React

npx create-react-app cypress-todo-app
cd cypress-todo-app

Paso 2: Construir la Aplicación Todo

Implementa una interfaz sencilla donde los usuarios puedan agregar y eliminar elementos de tareas, luego inicia el servidor de desarrollo:

npm start

Escribiendo Pruebas con Cypress

Paso 1: Crear un Nuevo Archivo de Prueba

Dentro de cypress/integration/, crea todo.spec.js.

Paso 2: Escribir las Pruebas

describe('Todo App', () => {
  beforeEach(() => {
    cy.visit('/');
  });

  it('Displays the app title', () => {
    cy.contains('h1', 'Todo App');
  });

  it('Can add a new todo item', () => {
    const newItem = 'Buy milk';
    cy.get('input[name="new-todo"]').type(`${newItem}{enter}`);
    cy.get('.todo-list').should('contain', newItem);
  });

  it('Can remove a todo item', () => {
    const itemToRemove = 'Buy milk';
    cy.get('.todo-list')
      .contains(itemToRemove)
      .parent()
      .find('.delete-button')
      .click();
    cy.get('.todo-list').should('not.contain', itemToRemove);
  });
});

Paso 3: Ejecutar las Pruebas

npx cypress open

Selecciona todo.spec.js para ejecutar las pruebas de forma interactiva.

Ejecutando Pruebas y Analizando los Resultados

El test runner de Cypress muestra cada comando a medida que se ejecuta. Puedes pasar el cursor sobre cualquier comando en el log para ver un snapshot de la aplicación en ese punto. Las pruebas fallidas generan capturas de pantalla automáticamente, y la grabación en video captura la ejecución completa.

Funcionalidades Avanzadas

Fixtures

Las fixtures cargan datos estáticos desde archivos hacia tus pruebas:

cy.fixture('user.json').then((user) => {
  // Use user data in your tests
});

Comandos Personalizados

El código de configuración repetido debe ir en comandos personalizados, no copiado entre specs.

En cypress/support/commands.js:

Cypress.Commands.add('login', (email, password) => {
  cy.visit('/login');
  cy.get('input[name="email"]').type(email);
  cy.get('input[name="password"]').type(password);
  cy.get('form').submit();
});

Usa el comando personalizado en tus pruebas:

cy.login('test@example.com', 'password123');

Integración Continua con Cypress

Ejemplo con GitHub Actions

Crea un archivo .github/workflows/cypress.yml:

name: Cypress Tests

on: [push]

jobs:
  cypress-run:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Install Dependencies
        run: npm install
      - name: Run Cypress Tests
        run: npx cypress run

Esto ejecuta Cypress en modo headless en cada push.

Conclusión

Vale la pena adoptar Cypress si tu equipo ha sufrido con pruebas Selenium inestables o con el ciclo de retroalimentación lento de las herramientas tradicionales de E2E. La arquitectura in-browser resuelve el problema de temporización desde la raíz. La GUI interactiva hace que depurar sea práctico en lugar de doloroso. Empieza con un puñado de pruebas que cubran los flujos de usuario más utilizados, consigue que pasen de forma confiable en CI y expande desde ahí.

Recursos Adicionales