ソフトウェアの品質を保つためには単体テスト(unit
test)が重要です。JavaScript/TypeScriptでのテストフレームワークとしてはJestなどが有名ですが、ここではViteエコシステム向けに開発されたVitestを使用します。Vitestは高速なビルドツールであるViteに統合された次世代のテストフレームワークで、Jestと互換性のあるAPIを提供します。そのため、Jestで使われるdescribe
やtest/it
、expect
といった関数を利用してテストを書くことができます。
Vitestを使うことで、VueやReactの開発環境(Viteベース)とシームレスに統合されたテスト実行が可能です。本章では、Vitestをプロジェクトに導入し、ごく基本的なテストを書いて実行する手順を学びます。
Vitestの導入はnpm install -D vitest
で行い、package.json
の"scripts"
に"test": "vitest"
を追加しておくとnpm run test
でテストを実行できます。テストファイル名は通常*.test.js
や*.spec.ts
といった形式にし、ソースコードと分けて配置します。
それでは、簡単な関数とそのテストを書いてみましょう。例として、二つの数値の和を返す関数sum
を作成し、それが正しく動作することをテストします。
/*** sum.js ***/
export function sum(a, b) {
return a + b;
}
/*** sum.test.js ***/
import { test, expect } from 'vitest';
import { sum } from './sum.js';
test('1 + 2 は 3 を返す', () => {
expect(sum(1, 2)).toBe(3);
});
解説: sum.js
(および sum.ts
)
では、単純に二つの引数を加算して返す関数sum
を定義・エクスポートしています。対応するテストファイルではimport
によりsum
関数を読み込み、test
関数を使ってテストケースを定義しています。test
関数の第一引数はテストの説明(文字列)、第二引数はテスト本体の関数です。
本体内ではexpect(sum(1, 2)).toBe(3)
と書いており、sum(1,2)
の結果が3
であることをアサート(断言)しています。toBe
は厳密な等価比較(===
相当)で期待値と比較するマッチャーです。他にもtoEqual
(オブジェクトの内容比較)やtoContain
(配列や文字列に要素が含まれるか)など様々なマッチャー関数があります。
Vitestを実行すると、このテストが走り、もし期待通りsum(1,2)
が3
を返せばテストはパスします。仮に実装や期待値が異なればテストは失敗し、どの部分が想定と違ったか報告されます。上記のテストケース程度であれば一瞬で実行が完了し、Vitestは結果をターミナル上に以下のように出力します:
✓ sum.test.js (1)
✓ 1 + 2 は 3 を返す
Test Files 1 passed (1)
Tests 1 passed (1)
Start at 10:00:00
Duration 312ms
このように、テストが成功するとグリーン(✓)で表示され、失敗すると詳細なエラーメッセージとともに赤色で表示されます。VitestはJestと互換性が高いため、既存のJest向け知識(describe
ブロックでテストをグループ化する、beforeEach
で事前処理を行う等)もそのまま活かせます。
テストコード自体もTypeScriptで記述できるため、開発中に型のミスがあればテストを書く段階で検出できます。VitestはViteのプロジェクトに組み込みやすく、ホットリロード的にテストを実行し直す機能も提供されています。まずは簡単な関数のテストから始めて、徐々にコンポーネント単位のテストやモックの使い方などに広げていきましょう。