Jestを使用したJavaScriptのテストの研究

公開

金曜日の夜に学んだことの簡単なまとめです。

今週とある案件でJSONに記述してあるイベント一覧を読み込んで直近のイベントをn件表示させるようなJavaScriptを書きました。正しく動作しているかテストが必要だろうということで、先方から頂いたエクセルのフォーマットに従ってテスト項目を書き、テストに使用したJSONとエビデンスとして画面キャプチャを入れておきました。

ただ、テストの途中で動作が意図通りになっていないなどの理由で修正が必要となり、再度テストを行うようなことがありました。やはりテストフレームワークを使用したテストが効率的なのではないかと考え、フレームワークの検討から行いました。

テストフレームワークの選定

以前会社のブログに「テストの自動化」という記事を書き、Jasmineを利用したことは記憶にありました。

時間も経過していますし、より良いものがあるかもしれないと探したところ、CodeGridの記事「Jestで始める! ユニットテスト」を見つけました。Jasmineの時はアサーションに利用するライブラリ等を別に選ぶ必要がありましたが、Jestはオールインワンであり手軽に利用できそうと考え、今回はJestを利用してみることにしました。

ちなみに、会社ブログを書いた時にもJestの存在は認識していたようです。

テストを書いてみる

npmでJestが利用できる環境を用意し、まずはテストを書いてみました。昨年Jasmineを利用した時と同じような感覚で書くことができました。テストコードを考える方が難しく時間もかかると感じました。今回はJSON形式のイベントデータを渡すと、今日以降のイベントデータが配列に追加されていることが確認できるようなコードを書きました。

なおテスト対象のソースコードはsrcディレクトリに、テストコードはtestディレクトリの中に〜.test.jsのような名前で保存しました。


global.$ = require('jquery');
global.moment = require('moment');
const EventList = require('../src/eventlist')

describe('期間指定イベントの処理', () => {
    let instance;
    beforeEach(() => {
        instance = new EventList();
    })
    it('今日以降のイベントが配列に追加されていること', () => {
        instance._pushRepeatEvent({
            "id": 1,
            "title": "お米フェア",
            "regularlyClosed": false,
            "startDate": "2019-10-01",
            "endDate": "2019-10-10",
            "repeatDayOfWeek": [],
            "priority": 0
        })
        expect((() => {
            let result = true
            const today = new Date()
            const todayInfoArray = [today.getFullYear(), today.getMonth(), today.getDate()]
            instance.eventsForDisplay.forEach((event) => {
                if (moment(event.startDate).isBefore(todayInfoArray)) {
                    result = false
                }
            })
            return result
        })()).toBeTruthy()
    })
})

テストの実行

Jasmineの時はブラウザを開いてテストを実行しましたが、Jestはコマンドラインでnpm testを実行しテストを走らせました。Visual Studio Codeでコードを書いていますので、同じ画面でテストの実行・テスト結果の確認ができるのは便利です。テストはNode.js上で実行するため、ロジックが正しいことはテストできてもIE11で動作するというのはテストできないなと思いました。
Visual Studio Codeでテストを実行した画面

最初にテストがFAILになることを確認し、その後テストがPASSするようにしました。

カバレッジの取得

今回最も便利だと感じたのはnpm test -- --coverageで簡単にカバレッジが取得できたことです。コードを眺めてテスト内容に漏れはないだろうかと悩んでいたのですが、その心配が一気に解決できることが分かりました。ブラウザ上でどこがテストできていないかを確認できるのはとても魅力的です。
ブラウザでカバレッジを表示した画面

ここまでのまとめ

テストはやはりテストフレームワークを使用して書くべきだなと感じました。後日機能追加が発生した場合でもデグレードしていないことを容易に確認でき、トラブルを防ぐこともできますしテスト時間も削減できるのではないかと考えます。正確なテストを書く時間を上手く確保できれば良いと思いますし、それが直近の課題になるでしょうか。(とはいえ、Excelに書くのも時間がかかるわけでして…)

HTMLを作成する部分のテストなどはどうするのだろう、非同期処理のテストはどうするのだろう、等の疑問がありますが、また時間を見つけて勉強したいと考えています。

使用したコードはGitHubのlearning-jestに置いています。