テスト
Nuxtアプリケーションのテスト方法。
If you are a module author, you can find more specific information in the Module Author's guide.
Nuxtは、@nuxt/test-utils
を通じて、Nuxtアプリケーションのエンドツーエンドテストとユニットテストを第一級のサポートを提供します。これはテストユーティリティと設定のライブラリで、現在Nuxt自体で使用しているテストとモジュールエコシステム全体のテストを動力しています。
インストール
他のテスト依存関係を管理できるようにするために、@nuxt/test-utils
はさまざまなオプションのピア依存関係を提供しています。例えば:
- Nuxt環境のランタイムには
happy-dom
とjsdom
の間で選択できます - エンドツーエンドテストランナーには
vitest
、cucumber
、jest
、playwright
の間で選択できます playwright-core
は、組み込みのブラウザテストユーティリティを使用したい場合にのみ必要です(そして@playwright/test
をテストランナーとして使用していない場合)
npm i --save-dev @nuxt/test-utils vitest @vue/test-utils happy-dom playwright-core
ユニットテスト
現在、Nuxtランタイム環境が必要なコードのユニットテスト環境を提供しています。現在、vitest
のみをサポートしています(他のランタイムを追加する貢献は歓迎されます)。
セットアップ
-
@nuxt/test-utils/module
をnuxt.config
ファイルに追加します(オプション)。これにより、開発中にユニットテストを実行するためのVitest統合がNuxt DevToolsに追加されます。export default defineNuxtConfig({ modules: [ '@nuxt/test-utils/module' ] })
-
次の内容で
vitest.config.ts
を作成します:import { defineVitestConfig } from '@nuxt/test-utils/config' export default defineVitestConfig({ // any custom Vitest config you require })
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}
.
It is possible to set environment variables for testing by using the .env.test
file.
Nuxtランタイム環境の使用
デフォルトでは、@nuxt/test-utils
はデフォルトのVitest環境を変更しませんので、細かいオプトインを行い、他のユニットテストと一緒にNuxtテストを実行することができます。
テストファイルの名前に.nuxt.
を追加する(例:my-file.nuxt.test.ts
またはmy-file.nuxt.spec.ts
)か、テストファイル内に直接@vitest-environment nuxt
というコメントを追加することで、Nuxt環境をオプトインできます。
// @vitest-environment nuxt
import { test } from 'vitest'
test('my test', () => {
// ... test with Nuxt environment!
})
また、Vitest設定でenvironment: 'nuxt'
を設定することで、すべてのテストにNuxt環境を有効にすることができます。
// 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
// }
// }
// }
}
})
デフォルトでenvironment: 'nuxt'
を設定している場合、必要に応じてデフォルト環境からテストファイルごとにオプトアウトすることができます。
// @vitest-environment node
import { test } from 'vitest'
test('my test', () => {
// ... test without Nuxt environment!
})
When you run your tests within the Nuxt environment, they will be running in a happy-dom
or 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).
🎭 組み込みモック
@nuxt/test-utils
はDOM環境のためのいくつかの組み込みモックを提供しています。
intersectionObserver
デフォルトtrue
、IntersectionObserver APIの機能を持たないダミークラスを作成します
indexedDB
デフォルトfalse
、fake-indexeddb
を使用してIndexedDB APIの機能的なモックを作成します
これらはvitest.config.ts
ファイルのenvironmentOptions
セクションで設定できます:
import { defineVitestConfig } from '@nuxt/test-utils/config'
export default defineVitestConfig({
test: {
environmentOptions: {
nuxt: {
mock: {
intersectionObserver: true,
indexedDb: true,
}
}
}
}
})
🛠️ ヘルパー
@nuxt/test-utils
はNuxtアプリのテストを容易にするための多くのヘルパーを提供しています。
mountSuspended
mountSuspended
を使用すると、Nuxt環境内で任意のVueコンポーネントをマウントでき、非同期セットアップとNuxtプラグインからの注入へのアクセスが可能になります。
Under the hood, mountSuspended
wraps mount
from @vue/test-utils
, so you can check out the Vue Test Utils documentation for more on the options you can pass, and how to use this utility.
例:
// @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('can mount some component', async () => {
const component = await mountSuspended(SomeComponent)
expect(component.text()).toMatchInlineSnapshot(
'"This is an auto-imported component"'
)
})
// @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('can also mount an app', async () => {
const component = await mountSuspended(App, { route: '/test' })
expect(component.html()).toMatchInlineSnapshot(`
"<div>This is an auto-imported component</div>
<div> I am a global component </div>
<div>/</div>
<a href="/test"> Test link </a>"
`)
})
renderSuspended
renderSuspended
を使用すると、@testing-library/vue
を使用してNuxt環境内で任意のVueコンポーネントをレンダリングでき、非同期セットアップとNuxtプラグインからの注入へのアクセスが可能になります。
これはTesting Libraryのユーティリティ、例えばscreen
やfireEvent
と一緒に使用する必要があります。これらを使用するには、プロジェクトに@testing-library/vueをインストールしてください。
また、Testing Libraryはクリーンアップのためにテストグローバルにも依存しています。これらをVitest設定でオンにする必要があります。
渡されたコンポーネントは<div id="test-wrapper"></div>
内にレンダリングされます。
例:
// @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('can render some component', async () => {
await renderSuspended(SomeComponent)
expect(screen.getByText('This is an auto-imported component')).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('can also render an app', async () => {
const html = await renderSuspended(App, { route: '/test' })
expect(html).toMatchInlineSnapshot(`
"<div id="test-wrapper">
<div>This is an auto-imported component</div>
<div> I am a global component </div>
<div>Index page</div><a href="/test"> Test link </a>
</div>"
`)
})
mockNuxtImport
mockNuxtImport
を使用すると、Nuxtの自動インポート機能をモックできます。例えば、useStorage
をモックする場合は、次のようにします:
import { mockNuxtImport } from '@nuxt/test-utils/runtime'
mockNuxtImport('useStorage', () => {
return () => {
return { value: 'mocked storage' }
}
})
// your tests here
mockNuxtImport
can only be used once per mocked import per test file. It is actually a macro that gets transformed to vi.mock
and vi.mock
is hoisted, as described in the Vitest docs.
テスト間で異なる実装を提供する必要がある場合、Nuxtインポートをモックするには、vi.hoisted
を使用してモックを作成して公開し、それらのモックをmockNuxtImport
で使用します。そうすることで、モックされたインポートにアクセスし、テスト間で実装を変更することができます。テストの実行間でモックの状態変更を元に戻すために、モックを復元することを忘れないでください。
import { vi } from 'vitest'
import { mockNuxtImport } from '@nuxt/test-utils/runtime'
const { useStorageMock } = vi.hoisted(() => {
return {
useStorageMock: vi.fn(() => {
return { value: 'mocked storage'}
})
}
})
mockNuxtImport('useStorage', () => {
return useStorageMock
})
// Then, inside a test
useStorageMock.mockImplementation(() => {
return { value: 'something else' }
})
mockComponent
mockComponent
を使用すると、Nuxtのコンポーネントをモックできます。
最初の引数はPascalCaseでのコンポーネント名、またはコンポーネントの相対パスです。
二番目の引数はモックされたコンポーネントを返すファクトリ関数です。
例えば、MyComponent
をモックするには:
import { mockComponent } from '@nuxt/test-utils/runtime'
mockComponent('MyComponent', {
props: {
value: String
},
setup(props) {
// ...
}
})
// relative path or alias also works
mockComponent('~/components/my-component.vue', async () => {
// or a factory function
return defineComponent({
setup(props) {
// ...
}
})
})
// or you can use SFC for redirecting to a mock component
mockComponent('MyComponent', () => import('./MockComponent.vue'))
// your tests here
注意: ファクトリ関数内ではローカル変数を参照することはできません。Vue APIや他の変数にアクセスする必要がある場合は、ファクトリ関数内でそれらをインポートする必要があります。
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
を使用すると、モックデータを返すNitroエンドポイントを作成できます。APIからデータを取得して表示するコンポーネントをテストしたい場合に便利です。
最初の引数はエンドポイント名(例:/test/
)です。
二番目の引数はモックデータを返すファクトリ関数です。
例えば、/test/
エンドポイントをモックするには:
import { registerEndpoint } from '@nuxt/test-utils/runtime'
registerEndpoint('/test/', () => ({
test: 'test-field'
}))
デフォルトでは、リクエストはGET
メソッドを使用して行われます。関数の代わりにオブジェクトを二番目の引数として設定することで、別の方法を使用することができます。
import { registerEndpoint } from '@nuxt/test-utils/runtime'
registerEndpoint('/test/', {
method: 'POST',
handler: () => ({ test: 'test-field' })
})
注意: コンポーネントのリクエストが外部APIに行く場合、
baseURL
を使用して、Nuxt Environment Override Config ($test
)を使用して空にすることで、すべてのリクエストがNitroサーバーに行くようにすることができます。
エンドツーエンドテストとの競合
@nuxt/test-utils/runtime
と@nuxt/test-utils/e2e
は異なるテスト環境で実行する必要があり、同じファイルで使用することはできません。
エンドツーエンドテストとユニットテストの両方の機能を@nuxt/test-utils
で使用したい場合は、テストを別々のファイルに分けることができます。その後、特別な// @vitest-environment nuxt
コメントでファイルごとにテスト環境を指定するか、ランタイムユニットテストファイルの名前に.nuxt.spec.ts
拡張子を付けます。
app.nuxt.spec.ts
import { mockNuxtImport } from '@nuxt/test-utils/runtime'
mockNuxtImport('useStorage', () => {
return () => {
return { value: 'mocked storage' }
}
})
app.e2e.spec.ts
import { setup, $fetch } from '@nuxt/test-utils/e2e'
await setup({
setupTimeout: 10000,
})
// ...
@vue/test-utils
の使用
Nuxtでユニットテストを行うために@vue/test-utils
を単独で使用したい場合、Nuxtのコンポーザブル、自動インポート、またはコンテキストに依存しないコンポーネントのみをテストしている場合は、次の手順に従って設定できます。
-
必要な依存関係をインストールします
npm i --save-dev vitest @vue/test-utils happy-dom @vitejs/plugin-vue
-
次の内容で
vitest.config.ts
を作成します:import { defineConfig } from 'vitest/config' import vue from '@vitejs/plugin-vue' export default defineConfig({ plugins: [vue()], test: { environment: 'happy-dom', }, });
-
package.json
に新しいテストコマンドを追加します"scripts": { "build": "nuxt build", "dev": "nuxt dev", ... "test": "vitest" },
-
次の内容でシンプルな
<HelloWorld>
コンポーネントcomponents/HelloWorld.vue
を作成します:<template> <p>Hello world</p> </template>
-
この新しく作成されたコンポーネントのためのシンプルなユニットテスト
~/components/HelloWorld.spec.ts
を作成します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') }) })
-
vitestコマンドを実行します
npm run test
おめでとうございます、Nuxtで@vue/test-utils
を使用したユニットテストを開始する準備が整いました!ハッピーなテスティングを!
エンドツーエンドテスト
エンドツーエンドテストには、テストランナーとしてVitest、Jest、Cucumber、Playwrightをサポートしています。
セットアップ
@nuxt/test-utils/e2e
ヘルパーメソッドを利用する各 describe
ブロックでは、テストを開始する前にテストコンテキストを設定する必要があります。
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', () => {
// ...
})
})
内部的には、setup
は beforeAll
、beforeEach
、afterEach
、afterAll
で複数のタスクを実行して、Nuxtテスト環境を正しく設定します。
以下のオプションを setup
メソッドに使用してください。
Nuxt設定
rootDir
: テスト対象のNuxtアプリがあるディレクトリへのパス。- 型:
string
- デフォルト:
'.'
- 型:
configFile
: 設定ファイルの名前。- 型:
string
- デフォルト:
'nuxt.config'
- 型:
タイミング
setupTimeout
:setupTest
がその作業を完了するために許される時間(ミリ秒単位)(Nuxtアプリケーションのビルドや生成に関連するファイルを含む場合があります)。- 型:
number
- デフォルト:
60000
- 型:
機能
-
build
: 別のビルドステップを実行するかどうか。- 型:
boolean
- デフォルト:
true
(browser
またはserver
が無効の場合、またはhost
が提供されている場合はfalse
)
- 型:
-
server
: テストスイートのリクエストに応答するサーバーを起動するかどうか。- 型:
boolean
- デフォルト:
true
(host
が提供されている場合はfalse
)
- 型:
-
port
: 提供された場合、起動したテストサーバーのポートを値に設定します。- 型:
number | undefined
- デフォルト:
undefined
- 型:
-
host
: 提供された場合、新しいサーバーを構築して実行する代わりにテスト対象として使用するURL。デプロイされたアプリケーションバージョンや既に実行中のローカルサーバー(テスト実行時間を大幅に短縮する可能性があります)に対して「リアル」なエンドツーエンドテストを実行するのに便利です。以下のターゲットホストエンドツーエンド例を参照してください。- 型:
string
- デフォルト:
undefined
- 型:
-
browser
: Nuxtテストユーティリティは内部的にplaywright
を使用してブラウザテストを行います。このオプションが設定されている場合、ブラウザが起動され、続くテストスイートで制御できます。- 型:
boolean
- デフォルト:
false
- 型:
-
browserOptions
- 型:
object
以下のプロパティを持つtype
: 起動するブラウザのタイプ -chromium
、firefox
、またはwebkit
launch
: ブラウザを起動する際にplaywrightに渡されるオプションのobject
。完全なAPIリファレンスを参照してください.
- 型:
-
runner
: テストスイートのランナーを指定します。現在はVitestが推奨されています。- 型:
'vitest' | 'jest' | 'cucumber'
- デフォルト:
'vitest'
- 型:
ターゲット host
エンドツーエンド例
エンドツーエンドテストの一般的な使用例は、本番環境で通常使用される同じ環境で実行されているデプロイされたアプリケーションに対してテストを実行することです。
ローカル開発や自動デプロイパイプラインの場合、別のローカルサーバーに対してテストを実行する方が効率的であり、テストフレームワークがテスト間で再ビルドするのを待つよりも通常は速くなります。
エンドツーエンドテストのために別のターゲットホストを使用するには、単に setup
関数の host
プロパティに望むURLを提供してください。
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)
})
})
API
$fetch(url)
サーバーレンダリングされたページのHTMLを取得します。
import { $fetch } from '@nuxt/test-utils/e2e'
const html = await $fetch('/')
fetch(url)
サーバーレンダリングされたページのレスポンスを取得します。
import { fetch } from '@nuxt/test-utils/e2e'
const res = await fetch('/')
const { body, headers } = res
url(path)
テストサーバーが実行中のポートを含む、指定されたページの完全なURLを取得します。
import { url } from '@nuxt/test-utils/e2e'
const pageUrl = url('/page')
// 'http://localhost:6840/page'
ブラウザでのテスト
@nuxt/test-utils
内で Playwright を使用して組み込みサポートを提供しています。これはプログラム的にもPlaywrightテストランナーを介しても使用できます。
createPage(url)
vitest
、jest
、または cucumber
内で、createPage
を使用して設定された Playwright ブラウザインスタンスを作成し、オプションで実行中のサーバーのパスを指定することができます。Playwrightドキュメントで利用可能なAPIメソッドについてもっと知ることができます.
import { createPage } from '@nuxt/test-utils/e2e'
const page = await createPage('/page')
// `page` 変数から Playwright のすべての API をアクセスできます
Testing with Playwright Test Runner
We also provide first-class support for testing Nuxt within the Playwright test runner.
npm i --save-dev @playwright/test @nuxt/test-utils
このセクションの初めに述べた setup()
関数と同じ設定詳細で、グローバルNuxt設定を提供することができます。
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))
}
},
// ...
})
テストファイルでは、@nuxt/test-utils/playwright
から直接 expect
と test
を使用する必要があります:
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!')
})
または、テストファイル内で直接Nuxtサーバーを設定することもできます:
import { expect, test } from '@nuxt/test-utils/playwright'
test.use({
nuxt: {
rootDir: fileURLToPath(new URL('..', import.meta.url))
}
})
test('test', async ({ page, goto }) => {
await goto('/', { waitUntil: 'hydration' })
await expect(page.getByRole('heading')).toHaveText('Welcome to Playwright!')
})
※このページは Nuxt.js 公式ドキュメントの翻訳ページ(非公式)です。
公式ドキュメントの該当ページはこちら:
https://nuxt.com/docs/3.x/getting-started/testing