Testing utilities Nuxt provides
Nuxt provides @nuxt/test-utils, a library of test utilities and configuration that offers first-class support for end-to-end and unit testing. It powers the official Nuxt tests and tests throughout the module ecosystem.
Vitest is the only supported environment for Nuxt unit tests
Currently, @nuxt/test-utils only has support for vitest for unit testing code that needs a Nuxt runtime environment. Contributions to add other runtimes would be welcome.
Add @nuxt/test-utils/module to nuxt.config
To add Vitest integration to Nuxt DevTools for running unit tests in development, add '@nuxt/test-utils/module' to the modules array in nuxt.config.ts.
Vitest config setup with defineVitestProject
Create vitest.config.ts with defineConfig from vitest/config and defineVitestProject from @nuxt/test-utils/config. Configure projects for unit tests (test/unit/, environment: 'node'), e2e tests (test/e2e/, environment: 'node'), and Nuxt tests (test/nuxt/, environment: 'nuxt'). defineVitestProject is only for Nuxt-environment tests; end-to-end tests use regular node environment.
vitest.config.ts must be ESM or named vitest.config.mts
When importing @nuxt/test-utils in vitest config, you must specify 'type': 'module' in package.json or rename the vitest config file to vitest.config.mts or vitest.config.mjs.
Simple Nuxt vitest setup with defineVitestConfig
You can use a simpler setup with defineVitestConfig from @nuxt/test-utils/config, setting environment to 'nuxt' to run all tests in the Nuxt environment. You can optionally set environmentOptions with nuxt.rootDir, nuxt.domEnvironment ('happy-dom' or 'jsdom'), and nuxt.overrides.
Opt-out of Nuxt environment per test file
If using simple setup with environment: 'nuxt' by default, you can opt out per test file by adding // @vitest-environment node at the top. However, this approach is not recommended as it creates a hybrid environment where Nuxt Vite plugins run but the Nuxt entry and nuxtApp are not initialized, which can lead to hard-to-debug errors.
TypeScript support for test/nuxt/ directory
By default, test files in test/nuxt/ or tests/nuxt/ directories are automatically included in the Nuxt app TypeScript context, recognizing Nuxt aliases like ~/, @/, #imports and TypeScript auto-imports that work in your Nuxt app.
Configure TypeScript context for non-standard test directories
If you have tests in other directories that run in the Nuxt Vitest environment, add them to the Nuxt TypeScript context by setting typescript.tsConfig.include in nuxt.config.ts with paths relative to the generated .nuxt/tsconfig.json.
Built-in mock: intersectionObserver
The intersectionObserver mock is enabled by default (true) and creates a dummy class without functionality for the IntersectionObserver API. Configure it in vitest.config.ts under test.environmentOptions.nuxt.mock.intersectionObserver.
Built-in mock: indexedDB
The indexedDB mock is disabled by default (false) and uses fake-indexeddb to create a functional mock of the IndexedDB API. Configure it in vitest.config.ts under test.environmentOptions.nuxt.mock.indexedDb.
mountSuspended helper for component testing
mountSuspended allows you to mount any Vue component within the Nuxt environment, allowing async setup and access to injections from Nuxt plugins. It wraps mount from @vue/test-utils. Accepts @vue/test-utils mount options and a route property (initial route, or false to skip, default /).
mountSuspended example
import { mountSuspended } from '@nuxt/test-utils/runtime'; import { SomeComponent } from '#components'; it('can mount some component', async () => { const component = await mountSuspended(SomeComponent); expect(component.text()).toMatchInlineSnapshot('"This is an auto-imported component"'); });
renderSuspended helper for testing library integration
renderSuspended allows you to render any Vue component within the Nuxt environment using @testing-library/vue, allowing async setup and access to injections from Nuxt plugins. Use with utilities from Testing Library like screen and fireEvent. Install @testing-library/vue and enable testing globals in Vitest config. The component renders inside <div id="test-wrapper"></div>. Accepts @testing-library/vue render options and a route property (initial route, or false to skip, default /).
mockNuxtImport helper signature
mockNuxtImport allows you to mock Nuxt's auto import functionality. Signature: mockNuxtImport('importName', factory) or mockNuxtImport<typeof importName>('importName', (original) => {}) or mockNuxtImport(importReference, (original) => {}). Can only be used once per mocked import per test file as it is a macro transformed to vi.mock which is hoisted.
mockNuxtImport example for useState
import { mockNuxtImport } from '@nuxt/test-utils/runtime'; mockNuxtImport('useState', () => { return () => { return { value: 'mocked storage' } } });
mockComponent helper for component mocking
mockComponent allows you to mock Nuxt's component. First argument is the component name in PascalCase or relative path. Second argument is a factory function returning the mocked component. You can't reference local variables in the factory function since they are hoisted; import needed Vue APIs or variables inside the factory.
registerEndpoint helper for mocking Nitro endpoints
registerEndpoint allows you to create Nitro endpoints that return mocked data. First argument is endpoint name (e.g. '/test/'). Second argument is either a factory function returning mocked data, or an object with handler, optional method (HTTP method like 'GET', 'POST'), and optional once (boolean - handler used only for first matching request).
registerEndpoint example
import { registerEndpoint } from '@nuxt/test-utils/runtime'; registerEndpoint('/test/', () => ({ test: 'test-field' })); // or with method: registerEndpoint('/test/', { method: 'POST', handler: () => ({ test: 'test-field' }) });
Setup @vue/test-utils for standalone component testing
Install vitest @vue/test-utils happy-dom @vitejs/plugin-vue. Create vitest.config.ts with defineConfig from vitest/config, add vue plugin, set test.environment to 'happy-dom'. This approach is for unit testing components that don't rely on Nuxt composables, auto-imports, or context.
End-to-end testing runners supported by Nuxt
Nuxt supports Vitest, Jest, Cucumber, and Playwright as test runners for end-to-end testing.
E2E test setup with @nuxt/test-utils/e2e
In each describe block using @nuxt/test-utils/e2e helpers, call await setup({ /* options */ }) before the test. The setup function performs tasks in beforeAll, beforeEach, afterEach, and afterAll to set up the Nuxt test environment correctly.
E2E setup options: Nuxt Config
rootDir (string, default '.'): Path to directory with Nuxt app to test. configFile (string, default 'nuxt.config'): Name of configuration file.
E2E setup options: Timings
setupTimeout (number, default 120000 or 240000 on Windows): Milliseconds allowed for setupTest to complete (including building/generating files). teardownTimeout (number, default 30000): Milliseconds allowed for tearing down test environment, such as closing browser.
E2E setup options: Features
build (boolean, default true): Run separate build step. Set false if browser/server disabled or if host provided. server (boolean, default true): Launch server to respond to requests. Set false if host provided. port (number|undefined, default undefined): Set launched test server port. host (string, default undefined): URL to use as test target instead of building/running new server. browser (boolean, default false): Launch browser via playwright for browser testing. browserOptions (object): Properties type ('chromium'|'firefox'|'webkit'), launch (playwright browser launch options). runner ('vitest'|'jest'|'cucumber', default 'vitest'): Test runner. logLevel (number, default 1): Override consola log level for server subprocess. captureServerLogs (boolean, default true): Capture server stdout/stderr; when true, accessible via getServerLogs(); when false, inherits stdio behavior.
$fetch API for E2E testing
import { $fetch } from '@nuxt/test-utils/e2e'; const html = await $fetch('/'); Gets the HTML of a server-rendered page.
fetch API for E2E testing
import { fetch } from '@nuxt/test-utils/e2e'; const res = await fetch('/'); const { body, headers } = res; Gets the response of a server-rendered page.
url API for E2E testing
import { url } from '@nuxt/test-utils/e2e'; const pageUrl = url('/page'); // 'http://localhost:6840/page' Gets the full URL for a given page including the test server port.
getServerLogs API for E2E testing
import { getServerLogs } from '@nuxt/test-utils/e2e'; Returns lines captured from server subprocess stdout/stderr since last startServer() call or clearServerLogs(). Only populated when captureServerLogs is true (default).
clearServerLogs API for E2E testing
import { clearServerLogs } from '@nuxt/test-utils/e2e'; Clears captured server log lines. Useful between requests when asserting only logs from specific operations.
createPage API for browser testing
import { createPage } from '@nuxt/test-utils/e2e'; const page = await createPage('/page'); Creates a configured Playwright browser instance pointing at a path from the running server. Access all Playwright page APIs from the returned page variable.
Playwright Test Runner integration with Nuxt
Install @playwright/test @nuxt/test-utils. Configure playwright.config.ts with defineConfig and devices, extending ConfigOptions from @nuxt/test-utils/playwright. Set use.nuxt.rootDir to fileURLToPath of root directory. Import expect and test from @nuxt/test-utils/playwright, not @playwright/test.
Playwright test example with goto and waitUntil
import { expect, test } from '@nuxt/test-utils/playwright'; test('test', async ({ page, goto }) => { await goto('/', { waitUntil: 'hydration' }); await expect(page.getByRole('heading')).toHaveText('Welcome to Playwright!'); });
Configure Nuxt in Playwright test file directly
You can configure Nuxt server directly in test file using test.use({ nuxt: { rootDir: fileURLToPath(new URL('..', import.meta.url)) } }) instead of using playwright.config.ts.