Madogiwa Blog

主に技術系の学習メモに使っていきます。

フロントエンドのテストフレームワークをJestからVitestに移行するメモ

テストフレームワークをJestからVitestに移行するのを試してみたので手順とか躓いたところとかをメモ🗒

Vitestとは?

Vitestは、「A blazing fast unit-test framework powered by Vite ⚡️」とあるようにViteを使った単体テストフレームワークです。

vitest.dev

Viteに関してはこちら

madogiwa0124.hatenablog.com

JestからVitestに移行する

基本的には以下の公式のマイグレーション手順に従っていけば大丈夫です。

Migration Guide | Vitest

Vitestのインストール

以下の手順に従ってVitestをインストールします。

Getting Started | Vitest

$ npm install -D vitest

Vitest requires Vite >=v2.7.10 and Node >=v14

※上記の通り、VitestはViteに依存していますがpackage.jsonにdependenciesに記載されてるので明示的なinstallは不要

Vitestの構成ファイルを作成する

以下のリポジトリ内のサンプルを元に自身の環境に合わせたVitestの構成ファイルを作成します。

github.com

私はVue3を使っているのでvueを参考にして以下のような感じで作成しました。

/// <reference types="vitest" />

import { defineConfig } from "vite";
import Vue from "@vitejs/plugin-vue";

export default defineConfig({
  plugins: [Vue()],
  test: {
    globals: true,
    environment: "jsdom",
  },
  resolve: {
    alias: {
      vue: "vue/dist/vue.esm-bundler.js",
      "@": `${__dirname}/src`,
      "@js": `${__dirname}/src/javascripts`,
      "@css": `${__dirname}/src/styles`,
    },
  },
});

型エラーが出る場合は以下のようなtypesを設定をtsconfig.jsonでしてあげると解決すると思います。

{
    "types": ["node", "vitest/globals"],

Vitestはデフォルトでrootのvite.config.tsを読み込んでくれるので、以下のようにvite.config.tsにVitest用の構成を追記して管理することもできます。

/// <reference types="vitest" />

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import legacy from "@vitejs/plugin-legacy";

import getEntries from "./config/vite/util/getEntries";
const JAVASCRIPT_ENTRY_PATH = "./src/javascripts/entries/";
const HTML_ENTRY_PATH = "./src/";

export default defineConfig({
  build: {
    manifest: true,
    rollupOptions: {
      input: { ...getEntries(JAVASCRIPT_ENTRY_PATH), ...getEntries(HTML_ENTRY_PATH) },
    },
    outDir: "public",
    assetsDir: "packs",
  },
  test: {
    globals: true,
    environment: "jsdom",
  },
  plugins: [vue(), legacy({ targets: ["defaults", "not IE 11"] })],
  resolve: {
    alias: {
      vue: "vue/dist/vue.esm-bundler.js",
      "@": `${__dirname}/src`,
      "@js": `${__dirname}/src/javascripts`,
      "@css": `${__dirname}/src/styles`,
    },
  },
});

テストコードの修正

VitestはJestとテスト用のメソッド名が同じため普通にテストをしている分には特に修正の必要はありませんでした。

私は使ってなかったのですがCallbackMock周りをJestで使っている場合は以下を参考に修正が必要そうです。

Auto-Mocking Behaviour
Unlike Jest, mocked modules in /mocks are not loaded unless vi.mock() is called. If you need them to be mocked in every test, like in Jest, you can mock them inside setupFiles.

Done Callback
From Vitest v0.10.0, the callback style of declaring tests is deprecated. You can rewrite them to use async/await functions, or use Promise to mimic the callback style.

https://vitest.dev/guide/migration.html#migrating-from-jest

テストを実行する

後は以下のようにテスト実行するだけです ✨ ※カバレッジを出したい時はvitest run --coverageを使います。

$ npm run test

> vite_study@1.0.0 test
> vitest


 DEV  v0.10.0 /Users/jun.morita/Documents/repo/vite_study

 √ spec/components/TopImage.spec.ts (1)
 √ spec/components/JsCounter.spec.ts (1)
 √ spec/components/TsCounter.spec.ts (1)

 Snapshots  2 obsolete
            ↳ spec/components/JsCounter.spec.ts
              · components/jsCounter.vue 初期表示 snapshot 1
            ↳ spec/components/TsCounter.spec.ts
              · components/tsCounter.vue 初期表示 snapshot 1

Test Files  3 passed (3)
     Tests  3 passed (3)
      Time  881ms (in thread 38ms, 2319.36%)


 PASS  Waiting for file changes...
       press h to show help, press q to quit

おわりに

個人の規模の小さいサンプルだったからかもですが、思ったよりもスッとJestからVitestに乗り換えることができました。 Viteでbuildしていると構成ファイルを統一できるのも管理が楽で良いですね⚡️

Vite/Vitest/Vue3/TypeScriptな構成のサンプルリポジトリも以下で公開してみました。

github.com