mizdra's blog

ぽよぐらみんぐ

vscode-jest を導入してテストの開発体験を向上させる

この記事は JavaScript Advent Calendar 2021 の 12日目です。11日目は なかがわはじめ さんの 「Array.prototype.reduce()とかのprototypeってなに?」 でした。


Jest は JavaScript のテスティングフレームワークです。Node.js で動くアプリケーションのテストや、React を使った Web アプリケーションのテストなど、様々なプロジェクトのテストをサポートしています。また、エディタ向けに拡張機能やプラグインも公開されています。

(各拡張機能のサポート状況によりますが) これらの拡張機能を使うと、エディタ上から Jest によるテストの実行やエディタへのテスト結果の表示、breakpoint を使ったテストの実行などができるようになります。こうした便利な機能を活用することで、テストの開発体験が大きく向上します。

この記事では vscode-jest を対象に、実際にどのように導入して、どういった機能が利用できるのかについて紹介します。

前提

まず vscode-jest を導入する前に、Jest が導入済みのプロジェクトを用意して下さい。この記事では以下のようなjest.config.jsで構成されるプロジェクトを例に解説していきます。

// @ts-check

/** @typedef {import('ts-jest/dist/types')} */
/** @type {import('@jest/types').Config.InitialOptions} */
module.exports = {
  preset: 'ts-jest',
  // test/ 配下にテストファイルがある想定
  testMatch: ['<rootDir>/test/**/*.test.ts?(x)'],
  globals: {
    'ts-jest': {
      tsconfig: 'tsconfig.test.json',
    },
  },
};

また、 Jest の テストを実行する npm-scripts も用意しておいて下さい。あとで使います。script 名はtestでもjestでも何でも良いです。

{
  "scripts": {
    // `npm run test` or `yarn test` で実行できる npm-scripts
    "test": "jest"
  },
}

vscode-jest の導入

準備ができたので、早速導入してみます。まずは以下のリンクから拡張機能をインストールしましょう。

marketplace.visualstudio.com

続けて jest.jestCommandLineというオプションを.vscode/settings.jsonに追加して下さい。これは Jest の起動方法を vscode-jest に教えてやるためのものです。事前に準備した Jest を起動する npm-script を書きましょう。yarn を使っていて、Jest を起動する npm-script の名前がtestなら、以下のように書きます。

// .vscode/settings.json
{
    "jest.jestCommandLine": "yarn run test",
}

vscode-jest はこのコマンドを使い、--watchオプションなどを付けてテストの自動実行を実現しています。そのため、npm を利用している場合は--を末尾に付けたコマンドを記入しなければなりません。ハマりやすいので注意して下さい。

// .vscode/settings.json
{
    // vscode-jest に jest を実行するコマンドを教えてやる
    // NOTE: `vscode-jest` はこのコマンドに `--watch` などのオプションを渡して実行するので、
    // `--` を明示してオプションが続けて渡せるようにしておく必要がある。
    "jest.jestCommandLine": "npm run test --",
}

これで完了です! ファイルの変更を保存して、VSCode を再起動してみて下さい。

各種機能の説明

インストールが完了すると、テストファイルの行番号の左にチェックマークが表示されたり、サイドバーに三角フラスコのメニューが追加されているはずです。1つずつ説明していきます。

エディタパネル

まず右側のエディタパネルから。行番号横の左にあるチェックマークは、テストの実行結果を示しています。passed なら緑のマークが、failed なら赤色のマークが表示されます。VSCode 起動時に自動的にテストが実行されるようになっており、起動した直後かつすべて pass していれば、すべてのテストケースに緑のマークが表示されているはずです。failed の場合は、assertion に失敗した行に赤の下線が引かれます。その行にマウスでホバーすると、失敗した原因のレポートを確認できます。

vscode-jest はテストの自動実行をサポートしています。そのためファイルを変更すると、関連するテストが自動的に実行されます。試してみましょう。

youtu.be

ちなみに全てのテストが自動実行される訳ではなく、モジュール同士の依存関係を理解して必要なテストファイルのみ実行してくれるようになっています。内部的には Jest の--watchオプションを用いているため、基本的にはjest --watchと同じ挙動をします。

Test Explorer

サイドバーに追加された三角フラスコアイコンのボタンを押すと、Test Explorer という機能が利用できます。これを使うと Jest のテストケースを一覧できます。

各テストケースの名前にホバーすると、「テストのデバッグ」ボタンと、「テストに移動」ボタンが表示されます。「テストに移動」ボタンを押すと、エディタパネルのほうで当該テストケースのあるファイルを開いて、その行にフォーカスを当ててくれます。これが地味に便利です。「テストのデバッグ」ボタンについては後で説明します。

上のほうにあるコンソールのようなアイコンのボタンを押すと、Jest のテストレポートをコンソール上で見ることができます。jest--watchで表示されるようなログがそのまま流れてきます。先程紹介した赤線にホバーした時に表示されるレポートはただのプレーンなテキストによるものでしたが、こちらは色付されているので、ちょっと見やすいです。かゆいところに手が届く感じがして良いですね。

デバッガーを利用する

vscode-jest は VSCode の組み込みデバッガーとの連携をサポートしています。これを使うと、breakpoint を使ったテストの実行などができます。

vscode-jest からデバッガーを利用するには、VSCode のデバッガー向けの設定ファイル (.vscode/launch.json) が必要です。vscode-jest にはこのファイルを自動生成する機能が実装されており、F1 > Jest Setup Extension (Beta) > Setup Jest Debug Config > Generateとするだけで簡単に用意できます。

www.youtube.com

これで以下のように、Test Explorer にある「テストのデバッグ」ボタンから breakpoint などを使ったデバッグが利用できるようになります。エディタパネルから変数をホバーして格納されている値を参照したり、ローカル変数一覧を参照したり、デバッグコンソールでローカル変数を使ってちょっとしたコードの評価をしたりできます。

www.youtube.com

以上が vscode-jest の各種機能の紹介でした。ちょっとした設定を書くだけで、これだけの機能が使えるのは驚きですね。エディタを離れることなくテスト結果が即参照できるというというのは思いの外体験が良くて、これだけでも十分導入する価値があります。またデバッガーを使いこなせれば、非常に効率よくテストをデバッグできます。こちらも是非導入してみてください。

本当はデバッガーの使い方などについてもっと丁寧に解説したかったのですが、非常に機能が豊富で説明しきれないので、都度他の資料を当たって下さい。

Tips: VSCode の起動時にテストを自動実行しないようにする

VSCode を起動すると、vscode-jest は自動的にテストを実行して、結果を表示してくれます。これは大変便利なのですが、VSCode の起動時に行われる VSCode 本体の初期化や、他の拡張機能の初期化のためのリソースを奪ってしまいます。個人的にはエディタが立ち上がったら素早くファイルを編集できるようになってほしいという思いがあり、起動時のテストの自動実行はおせっかいに感じています。

そこで id:mizdra は以下のような設定を.vscode/settings.jsonに書き、起動時にテストが自動実行されないようにしています。VSCode 上でファイルが変更されたらテストが自動実行がされる点は変わらないので、普段の開発体験への影響もほとんどありません。オススメです。

// .vscode/settings.json
{
  // VSCode の起動時に自動で jest のテストを走らせないように。
  // VSCode 起動時は色々な拡張機能の初期化処理が走っているので、
  // あまりカジュアルに起動時に処理を実行したくない、という狙いがある。
  // *.ts ファイルが変更されたら jest のテストが自動実行がされる点は変わらないので、
  // これで開発体験が損なわれることはないはず。
  "jest.autoRun": { "watch": true }
}

追記 (2022-11-17)

場合によっては Jest の起動がマシンの負荷になって、開発体験が悪くなることがあります (ファイルを保存する度に CPU が 100% に張り付くなど / Developer: Open Process Explorer を見よう!)。そこで id:mizdra は最近はテストファイルを保存した時のみテストを走らせるようにしています。

// .vscode/settings.json
{
  // VSCode の起動時に自動で jest のテストを走らせないように。
  // VSCode 起動時は色々な拡張機能の初期化処理が走っているので、
  // あまりカジュアルに起動時に処理を実行したくない、という狙いがある。
  // *.ts ファイルが変更されたら jest のテストが自動実行がされる点は変わらないので、
  // これで開発体験が損なわれることはないはず。
  "jest.autoRun": {
      "watch": false,
      // 加えて、普段のコーディングの時にいちいちテストが走っていては開発体験が悪いので、
      // テストファイルを保存したときにのみテストを走らせるように。
      "onSave": "test-file"
  },
}

逆にテストを先に書いて、後から実装を書く開発方法 (テスト駆動開発など) とは相性悪いので、そういう場合はこのオプションは不要かもしれません。もしくはテスト駆動開発したければ npm run test -- --watch するとかでも良いかもです。

あと VSCode 起動時に jest のログを表示するターミナルが自動に開いてわずらわしいので、設定で off にしています。

// .vscode/settings.json
{
  // vscode 起動時に jest の実行結果を表示するターミナルを自動で開かないように
  "jest.showTerminalOnLaunch": false
}

まとめ

この記事では vscode-jest を使ったテストの開発体験の改善について紹介しました。ちょっとした設定を書くだけで非常に強力な機能が使えるので、皆さんも是非導入してみてください。実際に紹介した手法で vscode-jest を導入してみた PR も貼っておきますので、参考にしてみてください。

github.com

JavaScript Advent Calendar 2021 の明日の担当は @youtoy さんです!

ポケットモンスター・ポケモン・Pokémon・は任天堂・クリーチャーズ・ゲームフリークの登録商標です.

当ブログは @mizdra 個人により運営されており, 株式会社ポケモン及びその関連会社とは一切関係ありません.