Pruebas

Ejemplos

Aprenda a configurar Next.js con herramientas de pruebas comúnmente utilizadas: Cypress, Playwright y Jest con React Testing Library.

Cypress

Cypress es un ejecutor de pruebas utilizado para pruebas de extremo a extremo (E2E) y pruebas de componentes.

Inicio rápido

Puede usar create-next-app con el ejemplo with-cypress para comenzar rápidamente.

Terminal
npx create-next-app@latest --example with-cypress with-cypress-app

Configuración manual

Para comenzar con Cypress, instale el paquete cypress:

Terminal
npm install --save-dev cypress

Agregue Cypress al campo scripts de package.json:

package.json
{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "cypress:open": "cypress open"
  }
}

Ejecute Cypress por primera vez para generar ejemplos que usen su estructura de carpetas recomendada:

Terminal
npm run cypress:open

Puede revisar los ejemplos generados y la sección Writing Your First Test de la documentación de Cypress para familiarizarse con la herramienta.

¿Debería usar pruebas E2E o de componentes?

La documentación de Cypress contiene una guía sobre la diferencia entre estos dos tipos de pruebas y cuándo es apropiado usar cada uno.

Creando su primera prueba E2E con Cypress

Asumiendo las siguientes dos páginas de Next.js:

pages/index.js
import Link from 'next/link'

export default function Home() {
  return (
    <nav>
      <h1>Página de inicio</h1>
      <Link href="/about">Acerca de</Link>
    </nav>
  )
}
pages/about.js
export default function About() {
  return (
    <div>
      <h1>Página Acerca de</h1>
      <Link href="/">Página de inicio</Link>
    </div>
  )
}

Agregue una prueba para verificar que su navegación funciona correctamente:

cypress/e2e/app.cy.js
describe('Navegación', () => {
  it('debería navegar a la página acerca de', () => {
    // Comenzar desde la página de inicio
    cy.visit('http://localhost:3000/')

    // Encontrar un enlace con un atributo href que contenga "about" y hacer clic
    cy.get('a[href*="about"]').click()

    // La nueva URL debería incluir "/about"
    cy.url().should('include', '/about')

    // La nueva página debería contener un h1 con "Página Acerca de"
    cy.get('h1').contains('Página Acerca de')
  })
})

Puede usar cy.visit("/") en lugar de cy.visit("http://localhost:3000/") si agrega baseUrl: 'http://localhost:3000' al archivo de configuración cypress.config.js.

Creando su primera prueba de componentes con Cypress

Las pruebas de componentes construyen y montan un componente específico sin tener que empaquetar toda su aplicación o lanzar un servidor. Esto permite pruebas más eficientes que aún proporcionan retroalimentación visual y la misma API utilizada para las pruebas E2E de Cypress.

Nota importante: Dado que las pruebas de componentes no inician un servidor Next.js, capacidades como <Image /> y getServerSideProps que dependen de un servidor no funcionarán directamente. Consulte la documentación de Cypress para Next.js para ver ejemplos de cómo hacer que estas características funcionen en pruebas de componentes.

Asumiendo los mismos componentes de la sección anterior, agregue una prueba para validar que un componente renderiza el resultado esperado:

pages/about.cy.js
import AboutPage from './about.js'

describe('<AboutPage />', () => {
  it('debería renderizar y mostrar el contenido esperado', () => {
    // Montar el componente React para la página Acerca de
    cy.mount(<AboutPage />)

    // La nueva página debería contener un h1 con "Página Acerca de"
    cy.get('h1').contains('Página Acerca de')

    // Validar que un enlace con la URL esperada está presente
    // *Seguir* el enlace es más adecuado para una prueba E2E
    cy.get('a[href="/"]').should('be.visible')
  })
})

Ejecutando sus pruebas de Cypress

Pruebas E2E

Dado que las pruebas E2E de Cypress prueban una aplicación Next.js real, requieren que el servidor Next.js esté en ejecución antes de iniciar Cypress. Recomendamos ejecutar sus pruebas contra su código de producción para parecerse más al comportamiento de su aplicación.

Ejecute npm run build y npm run start, luego ejecute npm run cypress -- --e2e en otra ventana de terminal para iniciar Cypress y ejecutar su suite de pruebas E2E.

Nota importante: Alternativamente, puede instalar el paquete start-server-and-test y agregarlo al campo scripts de package.json: "test": "start-server-and-test start http://localhost:3000 cypress" para iniciar el servidor de producción de Next.js junto con Cypress. Recuerde reconstruir su aplicación después de nuevos cambios.

Pruebas de componentes

Ejecute npm run cypress -- --component para iniciar Cypress y ejecutar su suite de pruebas de componentes.

Preparándose para Integración Continua (CI)

Habrá notado que ejecutar Cypress hasta ahora ha abierto un navegador interactivo, lo cual no es ideal para entornos de CI. También puede ejecutar Cypress sin interfaz gráfica usando el comando cypress run:

package.json
{
  "scripts": {
    //...
    "e2e": "start-server-and-test dev http://localhost:3000 \"cypress open --e2e\"",
    "e2e:headless": "start-server-and-test dev http://localhost:3000 \"cypress run --e2e\"",
    "component": "cypress open --component",
    "component:headless": "cypress run --component"
  }
}

Puede aprender más sobre Cypress e Integración Continua de estos recursos:

Playwright

Playwright es un marco de pruebas que le permite automatizar Chromium, Firefox y WebKit con una sola API. Puede usarlo para escribir pruebas de Extremo a Extremo (E2E) y Integración en todas las plataformas.

Inicio rápido

La forma más rápida de comenzar es usar create-next-app con el ejemplo with-playwright. Esto creará un proyecto Next.js completo con Playwright configurado.

Terminal
npx create-next-app@latest --example with-playwright with-playwright-app

Configuración manual

También puede usar npm init playwright para agregar Playwright a un proyecto NPM existente.

Para comenzar manualmente con Playwright, instale el paquete @playwright/test:

Terminal
npm install --save-dev @playwright/test

Agregue Playwright al campo scripts de package.json:

package.json
{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "test:e2e": "playwright test"
  }
}

Creando su primera prueba E2E con Playwright

Asumiendo las siguientes dos páginas de Next.js:

pages/index.js
import Link from 'next/link'

export default function Home() {
  return (
    <nav>
      <Link href="/about">Acerca de</Link>
    </nav>
  )
}
pages/about.js
export default function About() {
  return (
    <div>
      <h1>Página Acerca de</h1>
    </div>
  )
}

Agregue una prueba para verificar que su navegación funciona correctamente:

import { test, expect } from '@playwright/test'

test('debería navegar a la página acerca de', async ({ page }) => {
  // Comenzar desde la página de inicio (baseURL se establece via webServer en playwright.config.ts)
  await page.goto('http://localhost:3000/')
  // Encontrar un elemento con el texto 'Acerca de' y hacer clic
  await page.click('text=Acerca de')
  // La nueva URL debería ser "/about" (baseURL se usa allí)
  await expect(page).toHaveURL('http://localhost:3000/about')
  // La nueva página debería contener un h1 con "Página Acerca de"
  await expect(page.locator('h1')).toContainText('Página Acerca de')
})
import { test, expect } from '@playwright/test'

test('debería navegar a la página acerca de', async ({ page }) => {
  // Comenzar desde la página de inicio (baseURL se establece via webServer en playwright.config.ts)
  await page.goto('http://localhost:3000/')
  // Encontrar un elemento con el texto 'Acerca de' y hacer clic
  await page.click('text=Acerca de')
  // La nueva URL debería ser "/about" (baseURL se usa allí)
  await expect(page).toHaveURL('http://localhost:3000/about')
  // La nueva página debería contener un h1 con "Página Acerca de"
  await expect(page.locator('h1')).toContainText('Página Acerca de')
})

Puede usar page.goto("/") en lugar de page.goto("http://localhost:3000/"), si agrega "baseURL": "http://localhost:3000" al archivo de configuración playwright.config.ts.

Ejecutando sus pruebas de Playwright

Dado que Playwright prueba una aplicación Next.js real, requiere que el servidor Next.js esté en ejecución antes de iniciar Playwright. Se recomienda ejecutar sus pruebas contra su código de producción para parecerse más al comportamiento de su aplicación.

Ejecute npm run build y npm run start, luego ejecute npm run test:e2e en otra ventana de terminal para ejecutar las pruebas de Playwright.

Nota importante: Alternativamente, puede usar la característica webServer para permitir que Playwright inicie el servidor de desarrollo y espere hasta que esté completamente disponible.

Ejecutando Playwright en Integración Continua (CI)

Playwright ejecutará sus pruebas en modo sin interfaz gráfica por defecto. Para instalar todas las dependencias de Playwright, ejecute npx playwright install-deps.

Puede aprender más sobre Playwright e Integración Continua de estos recursos:

Jest y React Testing Library

Jest y React Testing Library se usan frecuentemente juntos para Pruebas Unitarias. Hay tres formas en que puede comenzar a usar Jest dentro de su aplicación Next.js:

  1. Usando uno de nuestros ejemplos de inicio rápido
  2. Con el Compilador Rust de Next.js
  3. Con Babel

Las siguientes secciones explicarán cómo puede configurar Jest con cada una de estas opciones:

Inicio rápido

Puede usar create-next-app con el ejemplo with-jest para comenzar rápidamente con Jest y React Testing Library:

Terminal
npx create-next-app@latest --example with-jest with-jest-app

Configurando Jest (con el Compilador Rust)

Desde el lanzamiento de Next.js 12, Next.js ahora tiene configuración incorporada para Jest.

Para configurar Jest, instale jest, jest-environment-jsdom, @testing-library/react, @testing-library/jest-dom:

Terminal
npm install --save-dev jest jest-environment-jsdom @testing-library/react @testing-library/jest-dom

Cree un archivo jest.config.mjs en el directorio raíz de su proyecto y agregue lo siguiente:

jest.config.mjs
import nextJest from 'next/jest.js'

const createJestConfig = nextJest({
  // Proporcione la ruta a su aplicación Next.js para cargar next.config.js y archivos .env en su entorno de prueba
  dir: './',
})

// Agregue cualquier configuración personalizada para pasar a Jest
/** @type {import('jest').Config} */
const config = {
  // Agregue más opciones de configuración antes de que se ejecute cada prueba
  // setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],

  testEnvironment: 'jest-environment-jsdom',
}

// createJestConfig se exporta de esta manera para asegurar que next/jest pueda cargar la configuración de Next.js que es asíncrona
export default createJestConfig(config)

Internamente, next/jest está configurando automáticamente Jest para usted, incluyendo:

  • Configurar transform usando SWC
  • Simular automáticamente hojas de estilo (.css, .module.css, y sus variantes scss), importaciones de imágenes y next/font
  • Cargar .env (y todas las variantes) en process.env
  • Ignorar node_modules de la resolución y transformación de pruebas
  • Ignorar .next de la resolución de pruebas
  • Cargar next.config.js para banderas que habilitan transformaciones SWC

Nota importante: Para probar variables de entorno directamente, cárguelas manualmente en un script de configuración separado o en su archivo jest.config.js. Para más información, consulte Variables de Entorno de Prueba.

Configuración de Jest (con Babel)

Si optas por no usar el Compilador Rust de Next.js, necesitarás configurar Jest manualmente e instalar babel-jest e identity-obj-proxy además de los paquetes mencionados anteriormente.

Aquí tienes las opciones recomendadas para configurar Jest con Next.js:

jest.config.js
module.exports = {
  collectCoverage: true,
  // en node 14.x el proveedor de cobertura v8 ofrece buena velocidad y reportes aceptables
  coverageProvider: 'v8',
  collectCoverageFrom: [
    '**/*.{js,jsx,ts,tsx}',
    '!**/*.d.ts',
    '!**/node_modules/**',
    '!<rootDir>/out/**',
    '!<rootDir>/.next/**',
    '!<rootDir>/*.config.js',
    '!<rootDir>/coverage/**',
  ],
  moduleNameMapper: {
    // Manejar imports CSS (con módulos CSS)
    // https://jestjs.io/docs/webpack#mocking-css-modules
    '^.+\\.module\\.(css|sass|scss)$': 'identity-obj-proxy',

    // Manejar imports CSS (sin módulos CSS)
    '^.+\\.(css|sass|scss)$': '<rootDir>/__mocks__/styleMock.js',

    // Manejar imports de imágenes
    // https://jestjs.io/docs/webpack#handling-static-assets
    '^.+\\.(png|jpg|jpeg|gif|webp|avif|ico|bmp|svg)$/i': `<rootDir>/__mocks__/fileMock.js`,

    // Manejar alias de módulos
    '^@/components/(.*)$': '<rootDir>/components/$1',
  },
  // Agregar más opciones de configuración antes de ejecutar cada prueba
  // setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
  testPathIgnorePatterns: ['<rootDir>/node_modules/', '<rootDir>/.next/'],
  testEnvironment: 'jsdom',
  transform: {
    // Usar babel-jest para transpilar pruebas con el preset next/babel
    // https://jestjs.io/docs/configuration#transform-objectstring-pathtotransformer--pathtotransformer-object
    '^.+\\.(js|jsx|ts|tsx)$': ['babel-jest', { presets: ['next/babel'] }],
  },
  transformIgnorePatterns: [
    '/node_modules/',
    '^.+\\.module\\.(css|sass|scss)$',
  ],
}

Puedes aprender más sobre cada opción de configuración en la documentación de Jest.

Manejo de hojas de estilo e imports de imágenes

Las hojas de estilo e imágenes no se usan en las pruebas, pero importarlas puede causar errores, por lo que necesitarás simularlas. Crea los archivos de simulación referenciados en la configuración anterior - fileMock.js y styleMock.js - dentro de un directorio __mocks__:

__mocks__/fileMock.js
module.exports = {
  src: '/img.jpg',
  height: 24,
  width: 24,
  blurDataURL: 'data:image/png;base64,imagedata',
}
__mocks__/styleMock.js
module.exports = {}

Para más información sobre el manejo de recursos estáticos, consulta la documentación de Jest.

Opcional: Extender Jest con matchers personalizados

@testing-library/jest-dom incluye un conjunto de matchers personalizados convenientes como .toBeInTheDocument() que facilitan la escritura de pruebas. Puedes importar estos matchers para cada prueba agregando la siguiente opción al archivo de configuración de Jest:

jest.config.js
setupFilesAfterEnv: ['<rootDir>/jest.setup.js']

Luego, dentro de jest.setup.js, agrega el siguiente import:

jest.setup.js
import '@testing-library/jest-dom'

extend-expect fue eliminado en v6.0, así que si estás usando @testing-library/jest-dom antes de la versión 6, necesitarás importar @testing-library/jest-dom/extend-expect en su lugar.

Si necesitas agregar más opciones de configuración antes de cada prueba, es común agregarlas al archivo jest.setup.js mencionado anteriormente.

Opcional: Imports absolutos y alias de módulos

Si tu proyecto usa Alias de Módulos, necesitarás configurar Jest para resolver los imports haciendo coincidir la opción paths en el archivo jsconfig.json con la opción moduleNameMapper en el archivo jest.config.js. Por ejemplo:

tsconfig.json o jsconfig.json
{
  "compilerOptions": {
    "module": "esnext",
    "moduleResolution": "node",
    "baseUrl": "./",
    "paths": {
      "@/components/*": ["components/*"]
    }
  }
}
jest.config.js
moduleNameMapper: {
  '^@/components/(.*)$': '<rootDir>/components/$1',
}

Creando tus pruebas:

Agrega un script de pruebas a package.json

Agrega el ejecutable de Jest en modo watch a los scripts de package.json:

package.json
{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "test": "jest --watch"
  }
}

jest --watch volverá a ejecutar las pruebas cuando un archivo cambie. Para más opciones de CLI de Jest, consulta la documentación de Jest.

Crea tus primeras pruebas

Tu proyecto ahora está listo para ejecutar pruebas. Sigue la convención de Jest agregando pruebas a la carpeta __tests__ en el directorio raíz de tu proyecto.

Por ejemplo, podemos agregar una prueba para verificar si el componente <Home /> renderiza correctamente un encabezado:

__tests__/index.test.js
import { render, screen } from '@testing-library/react'
import Home from '../pages/index'
import '@testing-library/jest-dom'

describe('Home', () => {
  it('renderiza un encabezado', () => {
    render(<Home />)

    const heading = screen.getByRole('heading', {
      name: /welcome to next\.js!/i,
    })

    expect(heading).toBeInTheDocument()
  })
})

Opcionalmente, agrega una prueba de snapshot para rastrear cambios inesperados en tu componente <Home />:

__tests__/snapshot.js
import { render } from '@testing-library/react'
import Home from '../pages/index'

it('renderiza la página de inicio sin cambios', () => {
  const { container } = render(<Home />)
  expect(container).toMatchSnapshot()
})

Bueno saber: Los archivos de prueba no deben incluirse dentro del Enrutador de Páginas (Pages Router) porque cualquier archivo dentro del Pages Router se considera una ruta.

Ejecutando tu suite de pruebas

Ejecuta npm run test para correr tu suite de pruebas. Después de que tus pruebas pasen o fallen, notarás una lista de comandos interactivos de Jest que serán útiles a medida que agregues más pruebas.

Para lectura adicional, estos recursos pueden serte útiles:

Paquetes y ejemplos de la comunidad

La comunidad de Next.js ha creado paquetes y artículos que pueden serte útiles:

Para más información sobre qué leer a continuación, recomendamos:

  • pages/basic-features/environment-variables#test-environment-variables