--- title: Testing description: How to test your Nuxt application. navigation.icon: i-ph-check-circle-duotone --- ::tip If you are a module author, you can find more specific information in the [Module Author's guide](/docs/guide/going-further/modules#testing). :: Nuxt offers first-class support for end-to-end and unit testing of your Nuxt application via `@nuxt/test-utils`, a library of test utilities and configuration that currently powers the [tests we use on Nuxt itself](https://github.com/nuxt/nuxt/tree/main/test) and tests throughout the module ecosystem. ::tip{icon="i-ph-video-duotone" to="https://www.youtube.com/watch?v=yGzwk9xi9gU" target="_blank"} Watch a video from Alexander Lichter about getting started with the `@nuxt/test-utils`. :: ## Installation In order to allow you to manage your other testing dependencies, `@nuxt/test-utils` ships with various optional peer dependencies. For example: - you can choose between `happy-dom` and `jsdom` for a runtime Nuxt environment - you can choose between `vitest`, `cucumber`, `jest` and `playwright` for end-to-end test runners - `playwright-core` is only required if you wish to use the built-in browser testing utilities (and are not using `@playwright/test` as your test runner) ::code-group ```bash [yarn] yarn add --dev @nuxt/test-utils vitest @vue/test-utils happy-dom playwright-core ``` ```bash [npm] npm i --save-dev @nuxt/test-utils vitest @vue/test-utils happy-dom playwright-core ``` ```bash [pnpm] pnpm add -D @nuxt/test-utils vitest @vue/test-utils happy-dom playwright-core ``` ```bash [bun] bun add --dev @nuxt/test-utils vitest @vue/test-utils happy-dom playwright-core ``` :: ## Unit Testing We currently ship an environment for unit testing code that needs a [Nuxt](https://nuxt.com) runtime environment. It currently _only has support for `vitest`_ (although contribution to add other runtimes would be welcome). ### Setup 1. Add `@nuxt/test-utils/module` to your `nuxt.config` file (optional). It adds a Vitest integration to your Nuxt DevTools which supports running your unit tests in development. ```ts twoslash export default defineNuxtConfig({ modules: [ '@nuxt/test-utils/module' ] }) ``` 2. Create a `vitest.config.ts` with the following content: ```ts twoslash import { defineVitestConfig } from '@nuxt/test-utils/config' export default defineVitestConfig({ // any custom Vitest config you require }) ``` ::tip When importing `@nuxt/test-utils` in your vitest config, It is necessary to have `"type": "module"` specified in your `package.json` or rename your vitest config file appropriately. > ie. `vitest.config.m{ts,js}`. :: ### Using a Nuxt Runtime Environment By default, `@nuxt/test-utils` will not change your default Vitest environment, so you can do fine-grained opt-in and run Nuxt tests together with other unit tests. You can opt in to a Nuxt environment by adding `.nuxt.` to the test file's name (for example, `my-file.nuxt.test.ts` or `my-file.nuxt.spec.ts`) or by adding `@vitest-environment nuxt` as a comment directly in the test file. ```ts twoslash // @vitest-environment nuxt import { test } from 'vitest' test('my test', () => { // ... test with Nuxt environment! }) ``` You can alternatively set `environment: 'nuxt'` in your Vitest configuration to enable the Nuxt environment for **all tests**. ```ts twoslash // vitest.config.ts import { fileURLToPath } from 'node:url' import { defineVitestConfig } from '@nuxt/test-utils/config' export default defineVitestConfig({ test: { environment: 'nuxt', // you can optionally set Nuxt-specific environment options // environmentOptions: { // nuxt: { // rootDir: fileURLToPath(new URL('./playground', import.meta.url)), // domEnvironment: 'happy-dom', // 'happy-dom' (default) or 'jsdom' // overrides: { // // other Nuxt config you want to pass // } // } // } } }) ``` If you have set `environment: 'nuxt'` by default, you can then opt _out_ of the [default environment](https://vitest.dev/guide/environment.html#test-environment) per test file as needed. ```ts twoslash // @vitest-environment node import { test } from 'vitest' test('my test', () => { // ... test without Nuxt environment! }) ``` ::warning When you run your tests within the Nuxt environment, they will be running in a [`happy-dom`](https://github.com/capricorn86/happy-dom) or [`jsdom`](https://github.com/jsdom/jsdom) environment. Before your tests run, a global Nuxt app will be initialized (including, for example, running any plugins or code you've defined in your `app.vue`). This means you should take particular care not to mutate the global state in your tests (or, if you need to, to reset it afterwards). :: ### 🎭 Built-In Mocks `@nuxt/test-utils` provides some built-in mocks for the DOM environment. #### `intersectionObserver` Default `true`, creates a dummy class without any functionality for the IntersectionObserver API #### `indexedDB` Default `false`, uses [`fake-indexeddb`](https://github.com/dumbmatter/fakeIndexedDB) to create a functional mock of the IndexedDB API These can be configured in the `environmentOptions` section of your `vitest.config.ts` file: ```ts twoslash import { defineVitestConfig } from '@nuxt/test-utils/config' export default defineVitestConfig({ test: { environmentOptions: { nuxt: { mock: { intersectionObserver: true, indexedDb: true, } } } } }) ``` ### 🛠️ Helpers `@nuxt/test-utils` provides a number of helpers to make testing Nuxt apps easier. #### `mountSuspended` `mountSuspended` allows you to mount any Vue component within the Nuxt environment, allowing async setup and access to injections from your Nuxt plugins. ::alert{type=info} Under the hood, `mountSuspended` wraps `mount` from `@vue/test-utils`, so you can check out [the Vue Test Utils documentation](https://test-utils.vuejs.org/guide/) for more on the options you can pass, and how to use this utility. :: For example: ```ts twoslash 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('can mount some component', async () => { const component = await mountSuspended(SomeComponent) expect(component.text()).toMatchInlineSnapshot( '"This is an auto-imported component"' ) }) ``` ```ts twoslash 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('can also mount an app', async () => { const component = await mountSuspended(App, { route: '/test' }) expect(component.html()).toMatchInlineSnapshot(` "
Hello world
``` 5. Create a simple unit test for this newly created component `~/components/HelloWorld.spec.ts` ```ts twoslash import { describe, it, expect } from 'vitest' import { mount } from '@vue/test-utils' import HelloWorld from './HelloWorld.vue' describe('HelloWorld', () => { it('component renders Hello world properly', () => { const wrapper = mount(HelloWorld) expect(wrapper.text()).toContain('Hello world') }) }) ``` 6. Run vitest command ::code-group ```bash [yarn] yarn test ``` ```bash [npm] npm run test ``` ```bash [pnpm] pnpm run test ``` ```bash [bun] bun run test ``` :: Congratulations, you're all set to start unit testing with `@vue/test-utils` in Nuxt! Happy testing! ## End-To-End Testing For end-to-end testing, we support [Vitest](https://github.com/vitest-dev/vitest), [Jest](https://jestjs.io), [Cucumber](https://cucumber.io/) and [Playwright](https://playwright.dev/) as test runners. ### Setup In each `describe` block where you are taking advantage of the `@nuxt/test-utils/e2e` helper methods, you will need to set up the test context before beginning. ```ts twoslash [test/my-test.spec.ts] import { describe, test } from 'vitest' import { setup, $fetch } from '@nuxt/test-utils/e2e' describe('My test', async () => { await setup({ // test context options }) test('my test', () => { // ... }) }) ``` Behind the scenes, `setup` performs a number of tasks in `beforeAll`, `beforeEach`, `afterEach` and `afterAll` to set up the Nuxt test environment correctly. Please use the options below for the `setup` method. #### Nuxt Config - `rootDir`: Path to a directory with a Nuxt app to be put under test. - Type: `string` - Default: `'.'` - `configFile`: Name of the configuration file. - Type: `string` - Default: `'nuxt.config'` #### Timings - `setupTimeout`: The amount of time (in milliseconds) to allow for `setupTest` to complete its work (which could include building or generating files for a Nuxt application, depending on the options that are passed). - Type: `number` - Default: `60000` #### Features - `build`: Whether to run a separate build step. - Type: `boolean` - Default: `true` (`false` if `browser` or `server` is disabled, or if a `host` is provided) - `server`: Whether to launch a server to respond to requests in the test suite. - Type: `boolean` - Default: `true` (`false` if a `host` is provided) - `port`: If provided, set the launched test server port to the value. - Type: `number | undefined` - Default: `undefined` - `host`: If provided, a URL to use as the test target instead of building and running a new server. Useful for running "real" end-to-end tests against a deployed version of your application, or against an already running local server (which may provide a significant reduction in test execution timings). See the [target host end-to-end example below](#target-host-end-to-end-example). - Type: `string` - Default: `undefined` - `browser`: Under the hood, Nuxt test utils uses [`playwright`](https://playwright.dev) to carry out browser testing. If this option is set, a browser will be launched and can be controlled in the subsequent test suite. - Type: `boolean` - Default: `false` - `browserOptions` - Type: `object` with the following properties - `type`: The type of browser to launch - either `chromium`, `firefox` or `webkit` - `launch`: `object` of options that will be passed to playwright when launching the browser. See [full API reference](https://playwright.dev/docs/api/class-browsertype#browser-type-launch). - `runner`: Specify the runner for the test suite. Currently, [Vitest](https://vitest.dev) is recommended. - Type: `'vitest' | 'jest' | 'cucumber'` - Default: `'vitest'` ##### Target `host` end-to-end example A common use-case for end-to-end testing is running the tests against a deployed application running in the same environment typically used for Production. For local development or automated deploy pipelines, testing against a separate local server can be more efficient and is typically faster than allowing the test framework to rebuild between tests. To utilize a separate target host for end-to-end tests, simply provide the `host` property of the `setup` function with the desired URL. ```ts import { setup, createPage } from '@nuxt/test-utils/e2e' import { describe, it, expect } from 'vitest' describe('login page', async () => { await setup({ host: 'http://localhost:8787', }) it('displays the email and password fields', 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)` Get the HTML of a server-rendered page. ```ts twoslash import { $fetch } from '@nuxt/test-utils/e2e' const html = await $fetch('/') ``` #### `fetch(url)` Get the response of a server-rendered page. ```ts twoslash import { fetch } from '@nuxt/test-utils/e2e' const res = await fetch('/') const { body, headers } = res ``` #### `url(path)` Get the full URL for a given page (including the port the test server is running on.) ```ts twoslash import { url } from '@nuxt/test-utils/e2e' const pageUrl = url('/page') // 'http://localhost:6840/page' ``` ### Testing in a Browser We provide built-in support using Playwright within `@nuxt/test-utils`, either programmatically or via the Playwright test runner. #### `createPage(url)` Within `vitest`, `jest` or `cucumber`, you can create a configured Playwright browser instance with `createPage`, and (optionally) point it at a path from the running server. You can find out more about the API methods available from [in the Playwright documentation](https://playwright.dev/docs/api/class-page). ```ts twoslash import { createPage } from '@nuxt/test-utils/e2e' const page = await createPage('/page') // you can access all the Playwright APIs from the `page` variable ``` #### Testing with Playwright Test Runner We also provide first-class support for testing Nuxt within [the Playwright test runner](https://playwright.dev/docs/intro). ::code-group ```bash [yarn] yarn add --dev @playwright/test @nuxt/test-utils ``` ```bash [npm] npm i --save-dev @playwright/test @nuxt/test-utils ``` ```bash [pnpm] pnpm add -D @playwright/test @nuxt/test-utils ``` ```bash [bun] bun add --dev @playwright/test @nuxt/test-utils ``` :: You can provide global Nuxt configuration, with the same configuration details as the `setup()` function mentioned earlier in this section. ```ts [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