Vue 3 に Jest を導入してテスト環境を構築する
はじめに
最近、業務で Vue.js を使う機会が増えてきたため、Vue 3 関連の記事も書いていこうと思います。今回は、Vue 3 で Jest を導入し、テスト環境を構築する方法をまとめます。
Vue の公式ドキュメントでは Vitest を推奨していますが、Jest との比較のために Jest を導入しようとしたところ、思いのほかハマってしまいました。これから Vue でテストを始める方の参考になれば幸いです。
対象
- Vue でテストを導入したい方
- Jest を使った Vue 3 のテスト環境構築方法を知りたい方
環境
- Docker (image:
node:22-bullseye
) - MacOS (M3)
Jest の導入と設定
必要なライブラリをインストール
Jest を Vue 3 で使うために、以下のライブラリをインストールします。
npm install --save-dev jest ts-jest @vue/test-utils @vue/vue3-jest jest-environment-jsdom
パッケージ | 役割 |
---|---|
@vue/test-utils | Vue コンポーネントのテストを行うためのライブラリ |
jest | JavaScript のテストランナー(v29) |
ts-jest | TypeScript を Jest で直接実行できるようにする |
@vue/vue3-jest | Vue 3 の .vue ファイルを Jest で実行できるようにする |
jest-environment-jsdom | Jest の実行環境を jsdom (ブラウザ風の環境)にする |
Jest の設定詳細
以下の jest.config.js
を作成し、Jest の設定を行います。
const config = {
preset: "ts-jest", // TypeScript を Jest で実行するためのプリセット
testEnvironment: "jsdom", // ブラウザ環境をエミュレートするために jsdom を使用
moduleFileExtensions: ["vue", "js", "ts", "json"], // テスト対象のファイル拡張子
transform: {
"^.+\\.vue$": "@vue/vue3-jest", // .vue ファイルを変換するための設定
"^.+\\.(js|ts)$": ["ts-jest", { isolatedModules: true }], // TypeScript/JavaScript を Jest で実行できるように変換
},
collectCoverage: false, // カバレッジ収集を無効化(必要に応じて true に変更)
collectCoverageFrom: [
"src/**/*.{js,ts,vue}",
"!src/main.ts",
"!src/router/**",
"!node_modules/**",
],
moduleNameMapper: {
"^@/(.*)$": "<rootDir>/src/$1", // エイリアス `@` を `src/` にマッピング
},
testEnvironmentOptions: {
customExportConditions: ["node", "node-addons"], // Node.js 環境向けの設定
},
};
export default config;
Jest の動作を確認する
Jest は CommonJS で動作するため、Vue の .vue ファイルをテストする際には ① Vue → ② JavaScript (ESM) → ③ JavaScript (CommonJS)
の 3 段階の変換 が必要になります。
① Vue ファイルを JavaScript (ESM) に変換
Vue の .vue ファイルは、HTML のテンプレート <template>
、スクリプト <script>
、スタイル <style>
を含んだ特殊な形式です。
そのままでは JavaScript として実行できないため、@vue/vue3-jest
を使って .vue ファイルを JavaScript に変換します。
<template>
<button @click="count++">{{ count }}</button>
</template>
<script setup>
import { ref } from 'vue';
const count = ref(0);
</script>
import { ref } from 'vue';
export default {
setup() {
const count = ref(0);
return { count };
}
};
② JavaScript (ESM) を CommonJS に変換
Jest は CommonJS 形式で動作するため、JavaScript (ESM) の import / export
を require / module.exports に変換する必要があります。これを ts-jest
が担当します。
const vue = require('vue');
module.exports = {
setup() {
const count = vue.ref(0);
return { count };
}
};
③ Jest が変換後のファイルを実行してテストを実行
ここまでの変換を経て、Jest は .vue ファイルを適切に解釈し、テストを実行できるようになります。
よくあるエラーと解決策
1. Cannot find module '../components/TestVueJest.vue'
エラー
TypeScript を使っている場合、.vue ファイルを import しようとすると、
TypeScript も 「こんな拡張子のファイル知らないよ!」 となります。
その結果、次のようなエラーが出ます。
error TS2307: Cannot find module '../components/TestVueJest.vue' or its corresponding type declarations.
jest.config.js
の transform
設定にisolatedModules: true
を追加し「単独の JavaScript ファイルとして変換すれば OK!」 と解釈してもらいエラーを回避します。
transform: {
"^.+\\.vue$": "@vue/vue3-jest",
"^.+\\.(js|ts)$": ["ts-jest", { isolatedModules: true }],
},
2. ReferenceError: Vue is not defined
エラー
Vue 3 は ESM(ECMAScript Modules) で書かれていますが、Jest はデフォルトで CommonJS(CJS) 形式で動作します。そのため、Jest は Vue の import 文を適切に解釈できず、
「Vue って何?」 となってしまい、ReferenceError: Vue is not defined というエラーが発生することがあります。
jest.config.js
に以下を追加して、Jest が Vue
のエクスポートを解釈できるようにします。
testEnvironmentOptions: {
customExportConditions: ["node", "node-addons"],
},
終わりに
Vue の公式推奨は Vitest
ですが、Jest を使いたい場合でもいくつk設定を行えば動作させることができそうです。
実際にテストを書いて行く中で、他にもエラーが出てくるかもしれないので、どうしても必要ということでなければVitest
の方が良さそうという印象でした。