nuxt logo

Traducción de Documentación (No Oficial)

¡Pruebas!

Cómo probar tu aplicación Nuxt.

Si eres un autor de módulos, puedes encontrar información más específica en la guía para autores de módulos.

Nuxt ofrece soporte de primera clase para pruebas de extremo a extremo y pruebas unitarias de tu aplicación Nuxt a través de @nuxt/test-utils, una biblioteca de utilidades y configuraciones de prueba que actualmente impulsa las pruebas que usamos en Nuxt y pruebas en todo el ecosistema de módulos.

Instalación

Para permitirte gestionar tus otras dependencias de prueba, @nuxt/test-utils se envía con varias dependencias opcionales de pares. Por ejemplo:

  • puedes elegir entre happy-dom y jsdom para un entorno de ejecución de Nuxt
  • puedes elegir entre vitest, cucumber, jest y playwright para ejecutores de pruebas de extremo a extremo
  • playwright-core solo es necesario si deseas usar las utilidades de prueba de navegador integradas (y no estás usando @playwright/test como tu ejecutor de pruebas)
npm i --save-dev @nuxt/test-utils vitest @vue/test-utils happy-dom playwright-core

Pruebas Unitarias

Actualmente proporcionamos un entorno para pruebas unitarias de código que necesita un entorno de ejecución de Nuxt. Actualmente solo tiene soporte para vitest (aunque se agradecería la contribución para agregar otros entornos de ejecución).

Configuración

  1. Agrega @nuxt/test-utils/module a tu archivo nuxt.config (opcional). Agrega una integración de Vitest a tus Nuxt DevTools que admite ejecutar tus pruebas unitarias en desarrollo.

    export default defineNuxtConfig({
      modules: [
        '@nuxt/test-utils/module'
      ]
    })
    
  2. Crea un vitest.config.ts con el siguiente contenido:

    import { defineVitestConfig } from '@nuxt/test-utils/config'
    
    export default defineVitestConfig({
      // cualquier configuración personalizada de Vitest que necesites
    })
    

Al importar @nuxt/test-utils en tu configuración de vitest, es necesario tener "type": "module" especificado en tu package.json o renombrar tu archivo de configuración de vitest adecuadamente.

es decir, vitest.config.m{ts,js}.

Es posible establecer variables de entorno para pruebas usando el archivo .env.test.

Usando un Entorno de Ejecución de Nuxt

Por defecto, @nuxt/test-utils no cambiará tu entorno predeterminado de Vitest, por lo que puedes optar por incluir y ejecutar pruebas de Nuxt junto con otras pruebas unitarias.

Puedes optar por un entorno de Nuxt agregando .nuxt. al nombre del archivo de prueba (por ejemplo, mi-archivo.nuxt.test.ts o mi-archivo.nuxt.spec.ts) o agregando @vitest-environment nuxt como un comentario directamente en el archivo de prueba.

// @vitest-environment nuxt
import { test } from 'vitest'

test('mi prueba', () => {
  // ... ¡prueba con el entorno de Nuxt!
})

Alternativamente, puedes establecer environment: 'nuxt' en tu configuración de Vitest para habilitar el entorno de Nuxt para todas las pruebas.

// vitest.config.ts
import { fileURLToPath } from 'node:url'
import { defineVitestConfig } from '@nuxt/test-utils/config'

export default defineVitestConfig({
  test: {
    environment: 'nuxt',
    // opcionalmente puedes establecer opciones específicas del entorno de Nuxt
    // environmentOptions: {
    //   nuxt: {
    //     rootDir: fileURLToPath(new URL('./playground', import.meta.url)),
    //     domEnvironment: 'happy-dom', // 'happy-dom' (predeterminado) o 'jsdom'
    //     overrides: {
    //       // otra configuración de Nuxt que quieras pasar
    //     }
    //   }
    // }
  }
})

Si has establecido environment: 'nuxt' por defecto, puedes optar por no usar el entorno predeterminado por archivo de prueba según sea necesario.

// @vitest-environment node
import { test } from 'vitest'

test('mi prueba', () => {
  // ... ¡prueba sin el entorno de Nuxt!
})

Cuando ejecutas tus pruebas dentro del entorno de Nuxt, se ejecutarán en un entorno happy-dom o jsdom. Antes de que se ejecuten tus pruebas, se inicializará una aplicación global de Nuxt (incluyendo, por ejemplo, ejecutar cualquier plugin o código que hayas definido en tu app.vue).

Esto significa que debes tener especial cuidado de no mutar el estado global en tus pruebas (o, si necesitas hacerlo, restablecerlo después).

🎭 Mocks Integrados

@nuxt/test-utils proporciona algunos mocks integrados para el entorno DOM.

intersectionObserver

Por defecto true, crea una clase ficticia sin ninguna funcionalidad para la API de IntersectionObserver

indexedDB

Por defecto false, utiliza fake-indexeddb para crear un mock funcional de la API de IndexedDB

Estos se pueden configurar en la sección environmentOptions de tu archivo vitest.config.ts:

import { defineVitestConfig } from '@nuxt/test-utils/config'

export default defineVitestConfig({
  test: {
    environmentOptions: {
      nuxt: {
        mock: {
          intersectionObserver: true,
          indexedDb: true,
        }
      }
    }
  }
})

🛠️ Ayudantes

@nuxt/test-utils proporciona una serie de ayudantes para facilitar las pruebas de aplicaciones Nuxt.

mountSuspended

mountSuspended te permite montar cualquier componente de Vue dentro del entorno de Nuxt, permitiendo la configuración asíncrona y el acceso a inyecciones de tus plugins de Nuxt.

Internamente, mountSuspended envuelve mount de @vue/test-utils, por lo que puedes consultar la documentación de Vue Test Utils para obtener más información sobre las opciones que puedes pasar y cómo usar esta utilidad.

Por ejemplo:

// @noErrors
import { it, expect } from 'vitest'
import type { Component } from 'vue'
declare module '#components' {
  export const SomeComponent: Component
}
// ---cut---
// tests/components/SomeComponents.nuxt.spec.ts
import { mountSuspended } from '@nuxt/test-utils/runtime'
import { SomeComponent } from '#components'

it('puede montar algún componente', async () => {
    const component = await mountSuspended(SomeComponent)
    expect(component.text()).toMatchInlineSnapshot(
        '"Este es un componente importado automáticamente"'
    )
})

// @noErrors
import { it, expect } from 'vitest'
// ---cut---
// tests/components/SomeComponents.nuxt.spec.ts
import { mountSuspended } from '@nuxt/test-utils/runtime'
import App from '~/app.vue'

// tests/App.nuxt.spec.ts
it('también puede montar una aplicación', async () => {
    const component = await mountSuspended(App, { route: '/test' })
    expect(component.html()).toMatchInlineSnapshot(`
      "<div>Este es un componente importado automáticamente</div>
      <div> Soy un componente global </div>
      <div>/</div>
      <a href="/test"> Enlace de prueba </a>"
    `)
})

renderSuspended

renderSuspended te permite renderizar cualquier componente de Vue dentro del entorno de Nuxt usando @testing-library/vue, permitiendo la configuración asíncrona y el acceso a inyecciones de tus plugins de Nuxt.

Esto debe usarse junto con utilidades de Testing Library, por ejemplo, screen y fireEvent. Instala @testing-library/vue en tu proyecto para usar estas.

Además, Testing Library también depende de los globales de prueba para la limpieza. Debes activarlos en tu configuración de Vitest.

El componente pasado se renderizará dentro de un <div id="test-wrapper"></div>.

Ejemplos:

// @noErrors
import { it, expect } from 'vitest'
import type { Component } from 'vue'
declare module '#components' {
  export const SomeComponent: Component
}
// ---cut---
// tests/components/SomeComponents.nuxt.spec.ts
import { renderSuspended } from '@nuxt/test-utils/runtime'
import { SomeComponent } from '#components'
import { screen } from '@testing-library/vue'

it('puede renderizar algún componente', async () => {
  await renderSuspended(SomeComponent)
  expect(screen.getByText('Este es un componente importado automáticamente')).toBeDefined()
})
// @noErrors
import { it, expect } from 'vitest'
// ---cut---
// tests/App.nuxt.spec.ts
import { renderSuspended } from '@nuxt/test-utils/runtime'
import App from '~/app.vue'

it('también puede renderizar una aplicación', async () => {
  const html = await renderSuspended(App, { route: '/test' })
  expect(html).toMatchInlineSnapshot(`
    "<div id="test-wrapper">
      <div>Este es un componente importado automáticamente</div>
      <div> Soy un componente global </div>
      <div>Página de índice</div><a href="/test"> Enlace de prueba </a>
    </div>"
  `)
})

mockNuxtImport

mockNuxtImport te permite simular la funcionalidad de importación automática de Nuxt. Por ejemplo, para simular useStorage, puedes hacerlo así:

import { mockNuxtImport } from '@nuxt/test-utils/runtime'

mockNuxtImport('useStorage', () => {
  return () => {
    return { value: 'almacenamiento simulado' }
  }
})

// tus pruebas aquí

mockNuxtImport solo se puede usar una vez por importación simulada por archivo de prueba. En realidad, es un macro que se transforma en vi.mock y vi.mock se eleva, como se describe en la documentación de Vitest.

Si necesitas simular una importación de Nuxt y proporcionar diferentes implementaciones entre pruebas, puedes hacerlo creando y exponiendo tus simulaciones usando vi.hoisted, y luego usar esas simulaciones en mockNuxtImport. Luego tienes acceso a las importaciones simuladas y puedes cambiar la implementación entre pruebas. Ten cuidado de restaurar las simulaciones antes o después de cada prueba para deshacer los cambios de estado de las simulaciones entre ejecuciones.

import { vi } from 'vitest'
import { mockNuxtImport } from '@nuxt/test-utils/runtime'

const { useStorageMock } = vi.hoisted(() => {
  return {
    useStorageMock: vi.fn(() => {
      return { value: 'almacenamiento simulado'}
    })
  }
})

mockNuxtImport('useStorage', () => {
  return useStorageMock
})

// Luego, dentro de una prueba
useStorageMock.mockImplementation(() => {
  return { value: 'algo más' }
})

mockComponent

mockComponent te permite simular el componente de Nuxt. El primer argumento puede ser el nombre del componente en PascalCase, o la ruta relativa del componente. El segundo argumento es una función de fábrica que devuelve el componente simulado.

Por ejemplo, para simular MyComponent, puedes:

import { mockComponent } from '@nuxt/test-utils/runtime'

mockComponent('MyComponent', {
  props: {
    value: String
  },
  setup(props) {
    // ...
  }
})

// la ruta relativa o alias también funciona
mockComponent('~/components/my-component.vue', async () => {
  // o una función de fábrica
  return defineComponent({
    setup(props) {
      // ...
    }
  })
})

// o puedes usar SFC para redirigir a un componente simulado
mockComponent('MyComponent', () => import('./MockComponent.vue'))

// tus pruebas aquí

Nota: No puedes referenciar variables locales en la función de fábrica ya que se elevan. Si necesitas acceder a las API de Vue u otras variables, debes importarlas en tu función de fábrica.

import { mockComponent } from '@nuxt/test-utils/runtime'

mockComponent('MyComponent', async () => {
  const { ref, h } = await import('vue')

  return defineComponent({
    setup(props) {
      const counter = ref(0)
      return () => h('div', null, counter.value)
    }
  })
})

registerEndpoint

registerEndpoint te permite crear un endpoint de Nitro que devuelve datos simulados. Puede ser útil si deseas probar un componente que realiza solicitudes a una API para mostrar algunos datos.

El primer argumento es el nombre del endpoint (por ejemplo, /test/). El segundo argumento es una función de fábrica que devuelve los datos simulados.

Por ejemplo, para simular el endpoint /test/, puedes hacer:

import { registerEndpoint } from '@nuxt/test-utils/runtime'

registerEndpoint('/test/', () => ({
  test: 'campo-de-prueba'
}))

Por defecto, tu solicitud se realizará usando el método GET. Puedes usar otro método estableciendo un objeto como el segundo argumento en lugar de una función.

import { registerEndpoint } from '@nuxt/test-utils/runtime'

registerEndpoint('/test/', {
  method: 'POST',
  handler: () => ({ test: 'campo-de-prueba' })
})

Nota: Si tus solicitudes en un componente van a una API externa, puedes usar baseURL y luego dejarla vacía usando Nuxt Environment Override Config ($test) para que todas tus solicitudes vayan al servidor Nitro.

Conflicto con Pruebas de Extremo a Extremo

@nuxt/test-utils/runtime y @nuxt/test-utils/e2e necesitan ejecutarse en diferentes entornos de prueba y, por lo tanto, no se pueden usar en el mismo archivo.

Si deseas usar tanto la funcionalidad de pruebas de extremo a extremo como de pruebas unitarias de @nuxt/test-utils, puedes dividir tus pruebas en archivos separados. Luego, especifica un entorno de prueba por archivo con el comentario especial // @vitest-environment nuxt, o nombra tus archivos de prueba de unidad de entorno de ejecución con la extensión .nuxt.spec.ts.

app.nuxt.spec.ts

import { mockNuxtImport } from '@nuxt/test-utils/runtime'

mockNuxtImport('useStorage', () => {
  return () => {
    return { value: 'almacenamiento simulado' }
  }
})

app.e2e.spec.ts

import { setup, $fetch } from '@nuxt/test-utils/e2e'

await setup({
  setupTimeout: 10000,
})

// ...

Usando @vue/test-utils

Si prefieres usar @vue/test-utils por sí solo para pruebas unitarias en Nuxt, y solo estás probando componentes que no dependen de composables de Nuxt, importaciones automáticas o contexto, puedes seguir estos pasos para configurarlo.

  1. Instala las dependencias necesarias

    npm i --save-dev vitest @vue/test-utils happy-dom @vitejs/plugin-vue
    
  2. Crea un vitest.config.ts con el siguiente contenido:

    import { defineConfig } from 'vitest/config'
    import vue from '@vitejs/plugin-vue'
    
    export default defineConfig({
      plugins: [vue()],
      test: {
        environment: 'happy-dom',
      },
    });
    
  3. Agrega un nuevo comando para pruebas en tu package.json

    "scripts": {
      "build": "nuxt build",
      "dev": "nuxt dev",
      ...
      "test": "vitest"
    },
    
  4. Crea un componente simple <HelloWorld> components/HelloWorld.vue con el siguiente contenido:

    <template>
      <p>Hola mundo</p>
    </template>
    
  5. Crea una prueba unitaria simple para este componente recién creado ~/components/HelloWorld.spec.ts

    import { describe, it, expect } from 'vitest'
    import { mount } from '@vue/test-utils'
    
    import HelloWorld from './HelloWorld.vue'
    
    describe('HelloWorld', () => {
      it('el componente renderiza Hola mundo correctamente', () => {
        const wrapper = mount(HelloWorld)
        expect(wrapper.text()).toContain('Hola mundo')
      })
    })
    
  6. Ejecuta el comando de vitest

    npm run test
    

¡Felicidades, estás listo para comenzar a realizar pruebas unitarias con @vue/test-utils en Nuxt! ¡Felices pruebas!

Pruebas de Extremo a Extremo

Para pruebas de extremo a extremo, soportamos Vitest, Jest, Cucumber y Playwright como ejecutores de pruebas.

Configuración

En cada bloque describe donde estés aprovechando los métodos de ayuda de @nuxt/test-utils/e2e, necesitarás configurar el contexto de prueba antes de comenzar.

test/my-test.spec.ts
import { describe, test } from 'vitest'
import { setup, $fetch } from '@nuxt/test-utils/e2e'

describe('Mi prueba', async () => {
  await setup({
    // opciones del contexto de prueba
  })

  test('mi prueba', () => {
    // ...
  })
})

Detrás de escena, setup realiza una serie de tareas en beforeAll, beforeEach, afterEach y afterAll para configurar correctamente el entorno de prueba de Nuxt.

Por favor, usa las opciones a continuación para el método setup.

Configuración de Nuxt

  • rootDir: Ruta a un directorio con una aplicación Nuxt que se pondrá a prueba.
    • Tipo: string
    • Predeterminado: '.'
  • configFile: Nombre del archivo de configuración.
    • Tipo: string
    • Predeterminado: 'nuxt.config'

Tiempos

  • setupTimeout: La cantidad de tiempo (en milisegundos) para permitir que setupTest complete su trabajo (que podría incluir construir o generar archivos para una aplicación Nuxt, dependiendo de las opciones que se pasen).
    • Tipo: number
    • Predeterminado: 60000

Características

  • build: Si se debe ejecutar un paso de construcción separado.

    • Tipo: boolean
    • Predeterminado: true (false si browser o server están deshabilitados, o si se proporciona un host)
  • server: Si se debe lanzar un servidor para responder a las solicitudes en el conjunto de pruebas.

    • Tipo: boolean
    • Predeterminado: true (false si se proporciona un host)
  • port: Si se proporciona, establece el puerto del servidor de prueba lanzado al valor.

    • Tipo: number | undefined
    • Predeterminado: undefined
  • host: Si se proporciona, una URL para usar como objetivo de prueba en lugar de construir y ejecutar un nuevo servidor. Útil para ejecutar pruebas de extremo a extremo "reales" contra una versión desplegada de tu aplicación, o contra un servidor local ya en ejecución (lo que puede proporcionar una reducción significativa en los tiempos de ejecución de las pruebas). Consulta el ejemplo de extremo a extremo de host objetivo a continuación.

    • Tipo: string
    • Predeterminado: undefined
  • browser: Internamente, las utilidades de prueba de Nuxt usan playwright para llevar a cabo pruebas de navegador. Si esta opción está configurada, se lanzará un navegador y se podrá controlar en el conjunto de pruebas posterior.

    • Tipo: boolean
    • Predeterminado: false
  • browserOptions

    • Tipo: object con las siguientes propiedades
      • type: El tipo de navegador a lanzar - ya sea chromium, firefox o webkit
      • launch: object de opciones que se pasarán a playwright al lanzar el navegador. Consulta referencia completa de la API.
  • runner: Especifica el ejecutor para el conjunto de pruebas. Actualmente, se recomienda Vitest.

    • Tipo: 'vitest' | 'jest' | 'cucumber'
    • Predeterminado: 'vitest'
Ejemplo de extremo a extremo de host objetivo

Un caso de uso común para las pruebas de extremo a extremo es ejecutar las pruebas contra una aplicación desplegada que se ejecuta en el mismo entorno que normalmente se usa para Producción.

Para el desarrollo local o los pipelines de despliegue automatizados, probar contra un servidor local separado puede ser más eficiente y generalmente es más rápido que permitir que el marco de prueba reconstruya entre pruebas.

Para utilizar un host objetivo separado para pruebas de extremo a extremo, simplemente proporciona la propiedad host de la función setup con la URL deseada.

import { setup, createPage } from '@nuxt/test-utils/e2e'
import { describe, it, expect } from 'vitest'

describe('página de inicio de sesión', async () => {
  await setup({
    host: 'http://localhost:8787',
  })

  it('muestra los campos de correo electrónico y contraseña', async () => {
    const page = await createPage('/login')
    expect(await page.getByTestId('email').isVisible()).toBe(true)
    expect(await page.getByTestId('password').isVisible()).toBe(true)
  })
})

APIs

$fetch(url)

Obtén el HTML de una página renderizada en el servidor.

import { $fetch } from '@nuxt/test-utils/e2e'

const html = await $fetch('/')

fetch(url)

Obtén la respuesta de una página renderizada en el servidor.

import { fetch } from '@nuxt/test-utils/e2e'

const res = await fetch('/')
const { body, headers } = res

url(path)

Obtén la URL completa para una página dada (incluyendo el puerto en el que se está ejecutando el servidor de prueba).

import { url } from '@nuxt/test-utils/e2e'

const pageUrl = url('/page')
// 'http://localhost:6840/page'

Pruebas en un Navegador

Proporcionamos soporte integrado usando Playwright dentro de @nuxt/test-utils, ya sea programáticamente o a través del ejecutor de pruebas de Playwright.

createPage(url)

Dentro de vitest, jest o cucumber, puedes crear una instancia de navegador de Playwright configurada con createPage, y (opcionalmente) apuntarla a una ruta desde el servidor en ejecución. Puedes encontrar más información sobre los métodos de la API disponibles en la documentación de Playwright.

import { createPage } from '@nuxt/test-utils/e2e'

const page = await createPage('/page')
// puedes acceder a todas las APIs de Playwright desde la variable `page`

Pruebas con el Ejecutador de Pruebas de Playwright

También proporcionamos soporte de primera clase para probar Nuxt dentro del ejecutor de pruebas de Playwright.

npm i --save-dev @playwright/test @nuxt/test-utils

Puedes proporcionar configuración global de Nuxt, con los mismos detalles de configuración que la función setup() mencionada anteriormente en esta sección.

playwright.config.ts
import { fileURLToPath } from 'node:url'
import { defineConfig, devices } from '@playwright/test'
import type { ConfigOptions } from '@nuxt/test-utils/playwright'

export default defineConfig<ConfigOptions>({
  use: {
    nuxt: {
      rootDir: fileURLToPath(new URL('.', import.meta.url))
    }
  },
  // ...
})
Ver también Ver configuración de ejemplo completa

Tu archivo de prueba debería usar expect y test directamente desde @nuxt/test-utils/playwright:

tests/example.test.ts
import { expect, test } from '@nuxt/test-utils/playwright'

test('prueba', async ({ page, goto }) => {
  await goto('/', { waitUntil: 'hydration' })
  await expect(page.getByRole('heading')).toHaveText('¡Bienvenido a Playwright!')
})

Alternativamente, puedes configurar tu servidor Nuxt directamente dentro de tu archivo de prueba:

tests/example.test.ts
import { expect, test } from '@nuxt/test-utils/playwright'

test.use({
  nuxt: {
    rootDir: fileURLToPath(new URL('..', import.meta.url))
  }
})

test('prueba', async ({ page, goto }) => {
  await goto('/', { waitUntil: 'hydration' })
  await expect(page.getByRole('heading')).toHaveText('¡Bienvenido a Playwright!')
})