【 Nuxt3 × Vitest × Pinia × VeeValidate 】テスト実装時に必要な事

store に Pinia を使ってバリデーションには VeeValidate という作りで Nuxt3 を使った web アプリならよくありそうな構成に対して vitest でテストを書く機会があったのでポイントをいくつかまとめておこうと思います。

はじめに

まず Nuxt3 のプロジェクトで Vitest を動かすにあたり、 import の問題等で様々なエラーが出ると思います。

それらの解決方法は こちら の記事で詳しく書かれているのでこれらに沿って設定していけばある程度解決できると思います。ただ Nuxt3 × Vitest においては諸々設定が必要なのが面倒だというのは正直思う所です。。

上記の記事でも紹介されている nuxt-vitest ですが、 2023 年 10 月現在でもコミットは毎日のように行われている様なので早くプラグインを導入するだけでもう実行できるという状態になってほしい所です。しかし現状もその様にはなっていない様でした。

今回の記事では上記では記載の無い部分について自分が実装するにあたって必要があった部分を備忘録として残しておきます。

Pinia を使うにあたって

本プロジェクトでは store に pinia を使っているのですが、その都合上 setup ( vitest.config.ts で指定する全テストのセットアップ処理を記述している部分) にて以下の記述が必要でした。

// pinia セットアップ
setActivePinia(createPinia())

これだけ setup で行なっておけば後は各テストで問題なくアサーション等可能でした。

また、beforeEach で reset を行う事で各テストケースにおいて毎度 store 内部を reset してテストができるので記述しておいた方が良いかと思います。

beforeEach(() => {
    const testStore = useTestStore()
    testStroe.$reset()
})

VeeValidate によるバリデーション部分のテスト

VeeValidate の実装部分に関しては こちら の前回更新の記事にてどのようにバリデーションを行なっているか紹介しています。

これらを見ると分かりますがバリデーションは非同期で行われるため expect を行う際に処理を待つ必要があります。

以下の様な sleep 関数を実装してそれで 0.1 秒待ってから expect としても良いですが、環境によって必要な待ち時間が違っても嫌だし極力 sleep は使いたく無いのと、公式では flushPromises や waitForExpect を推奨している様でしたので今回は waitForExpect を使用しました。 ( 参考 )

export const sleep = (second: number) => new Promise((resolve) => setTimeout(resolve, second * 1000));

以下は waitForExpect を使いバリデーション実行後エラーが表示される事をテストするサンプルになります。

// バリデーション実行のボタンを押下
wrapper.find('#testButton').trigger('click')

// バリデーション部分で非同期処理を含むため expect の前に waitForExpect を使用
await waitForExpect(() => {
  expect(wrapper.findAll('#errMessage')[0].text()).to.toContain('コードは半角英数字で入力してください。');
});

最後に

まだまだ Nuxt3 × Vitest の面倒な部分は感じましたが、冒頭の nuxt-vitest もそうですが、 今後色々と改善されそうな気もするのでその際にはまた記事にしたいと思います。

また vscode で開発を行っていますが、vitest の拡張機能でエディタ上のボタンからテストの実行などが一応できるはずの様でした。しかし自分が試した限りでは個別でのテスト実行が拡張機能からは行えず (諸々エラーになり ) 仕方なく test.only('個別テスト’) のような形で個別でのテスト実行などを行っていました。

もしこの拡張機能で個別にエディタから実行できるなどありましたら是非ご共有お願いします 🙏

学習用書籍