今回は、Vitestを使ったテストの設定について書いていきます。
Vitest のセットアップ
まず、必要なパッケージを追加します。
npm install -D vitest @testing-library/react @testing-library/jest-dom jsdom @testing-library/user-event
ディレクトリ構成
frontend/
├─ app/
│ └─ src/
│ └─ sample.ts
├─ __tests__/
│ └─ sample.test.ts
├─ tsconfig.json
├─ vitest.config.ts
└─ package.json
モジュールのインストール
後述のvitest.config.jsで使うためのモジュールをインストールします。
npm install -D vite-tsconfig-paths
vitest.config.tsの作成と更新
import { defineConfig } from 'vitest/config'//←変更
import path from 'path';
// https://vite.dev/config/
export default defineConfig({
resolve:{
alias:{
"@":path.resolve(__dirname,".")// "@": path.resolve(__dirname, "./src")
},
},
test:{
globals:true,
environment:"node",
css:false
},
})
package.jsonの修正
{
"name": "my-next-app13",
"version": "0.1.0",
"private": true,
"type": "module",
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"test": "vitest",
"test:watch": "vitest --watch"
},
"dependencies": {
"@chakra-ui/icons": "^2.2.4",
"@chakra-ui/react": "^2.8.2",
"@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.1",
"@tailwindcss/vite": "^4.1.18",
"@vitejs/plugin-react": "^5.1.2",
"axios": "^1.13.2",
"framer-motion": "^12.23.24",
"next": "13.5.11",
"react": "^18",
"react-dom": "^18"
},
"devDependencies": {
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^16.3.1",
"@testing-library/user-event": "^14.6.1",
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"autoprefixer": "^10",
"eslint": "^8",
"eslint-config-next": "13.5.11",
"jsdom": "^27.4.0",
"postcss": "^8",
"prettier": "3.6.2",
"tailwindcss": "^3",
"typescript": "^5",
"vitest": "^4.0.16"
}
}
tsConfig.jsonの修正
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./*"]
},
"types": ["vitest/globals"]👈追加
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}
tsConfig.app.jsonの作成
{
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"target": "ES2022",
"useDefineForClassFields": true,
"lib": ["ES2022", "DOM", "DOM.Iterable"],
"module": "ESNext",
"types": ["vite/client","vitest/globals"],//「"vitest/globals"」を追加
"skipLibCheck": true,
"baseUrl": ".",
"paths": {
"@/*":[
"./src/*"
]
},
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"verbatimModuleSyntax": true,
"moduleDetection": "force",
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"erasableSyntaxOnly": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true
},
"include": ["src"]
}
tsConfig.node.jsonの作成
{
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
"target": "ES2023",
"lib": ["ES2023"],
"module": "ESNext",
"types": ["node", "vitest/globals"],//追加
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"verbatimModuleSyntax": true,
"moduleDetection": "force",
"noEmit": true,
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"erasableSyntaxOnly": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true
},
"include": ["vite.config.ts"]
}
テスト対象のコードの作成
export const add = (n:number)=>n+n;
テストコードの作成
import { describe,expect,test,vi } from "vitest";
import { add } from "@/app/src/sample";
describe('足し算',()=>{
test('2+2=4',()=>{
expect(add(2)).toBe(4);
})
});
テスト実行
テストは下記のコマンドで実行します。
npm run test
また、特定のテストファイルのみをテストしたい場合は下記のようにします。
テストファイルが格納されているディレクトリまで移動して、
cd frontend
下記のコマンドを実行します。
npx vitest run <テストフォルダ>/<テストファイル>
(例)
npx vitest run __tests__/sample.test.ts
カバレッジレポートの出力
カバレッジレポートの出力には、下記のライブラリが必要になります。
@vitest/coverage-v8
カバレッジの出力は下記のコマンドを実行します。
npx vitest run --coverage <テストフォルダ>/<テストファイル>
(例)
npx vitest run --coverage __tests__/sample.test.ts
そうすると、下記に「coverage」というフォルダが作成されます。

index.htmlを開くと下記のようにレポートがブラウザに表示されます。

トラブルシューティング
トラブル1
下記のエラーが表示された場合
failed to load config from C:\Users\xxx\Desktop\app\frontend\vitest.config.ts Error [ERR_REQUIRE_ESM]: require() of ES Module
C:\Users\xxx\Desktop\app\frontend\node_modules\vite\dist\node\index.js from C:\Users\xxx\Desktop\app\frontend\node_modules\vitest\dist\config.cjs not supported.
(原因)
❌ エラーの意味(重要)
Error [ERR_REQUIRE_ESM]:
require() of ES Module vite/dist/node/index.js
from vitest/dist/config.cjs not supported
これはつまり👇
・vitest.config.ts が ESM
・でもNode.jsがCommonJSとして読み込もうとしている
→ vite は ESM 専用なので explode 💥
(解決策)
package.json を ESM にする
frontend/package.json
{
"type": "module"
}
全体のpackage.json破棄の通りです。
{
"name": "my-next-app13",
"version": "0.1.0",
"private": true,
"type": "module",👈これを追加する
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"test": "vitest",
"test:watch": "vitest --watch"
},
"dependencies": {
"@chakra-ui/icons": "^2.2.4",
"@chakra-ui/react": "^2.8.2",
"@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.1",
"@tailwindcss/vite": "^4.1.18",
"@vitejs/plugin-react": "^5.1.2",
"axios": "^1.13.2",
"framer-motion": "^12.23.24",
"next": "13.5.11",
"react": "^18",
"react-dom": "^18"
},
"devDependencies": {
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^16.3.1",
"@testing-library/user-event": "^14.6.1",
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"autoprefixer": "^10",
"eslint": "^8",
"eslint-config-next": "13.5.11",
"jsdom": "^27.4.0",
"postcss": "^8",
"prettier": "3.6.2",
"tailwindcss": "^3",
"typescript": "^5",
"vitest": "^4.0.16"
}
}
トラブル2
下記のようなエラーが出た。
Error: Cannot find package '@/app/src/sample' imported from 'C:/Users/xxxx/Desktop/app/frontend/__tests__/sample..test.ts' ❯ __tests__/sample..test.ts:2:1 1| import { describe,expect,test,vi } from "vitest"; 2| import { add } from "@/app/src/sample";
(原因)
❌ エラーの正体
Cannot find package '@/app/src/sample'
これは Vitest が @ の意味を正しく解釈できていない 状態です。
今の import:
import { add } from "@/app/src/sample";
現在のディレクトリ構成は下記です。
frontend/
├─ app/
│ └─ src/
│ └─ sample.ts
├─ __tests__/
│ └─ sample.test.ts
├─ vitest.config.ts
しかし、今のvitest.config.tsは下記のようなっています。
alias: {
"@": path.resolve(__dirname, "./src")
}
つまり:
./src ❌ 存在しない
正しいのは ./app/src であるため、
そのため Vitest が
@/app/src/sample を解決できず、エラーになっています。
ちなみに、@ = frontend/を指しています。
なので、vitest.config.tsを下記のように修正します。
import { defineConfig } from 'vitest/config'//←変更
import path from 'path';
// https://vite.dev/config/
export default defineConfig({
resolve:{
alias:{
"@":path.resolve(__dirname,".")
},
},
test:{
globals:true,
environment:"node",
css:false
},
})
サイト
テストフレームワーク「Vitest」を使う方法
Jestの使い方を簡単に調べてみます
Vitestを使ったモダンなJavaScriptテスト入門