2020年 2月のJestセットアップ


ありとあらゆるリファレンスを読みまくってまとめました。
一番スッキリJestをセットアップしよう。

Jestとは

Facebookが開発したJavaScriptの単体テストフレームワーク。
Node上で動作するため、手軽にテストを実行できる事が特徴。

Jest · 🃏快適なJavaScriptのテスト

作業環境

  • Laravel 5.7
  • Docker on Mac
  • Vue.jsとかはLaravel mixのもの

セットアップ

Jestとかをnpm install

npm install --save-dev jest babel-jest @babel/core babel-core@bridge @babel/preset-env vue-jest @vue/test-utils

それぞれのひとこと説明

jest
Jest本体

babel-jest
babelとjestを連携させるもの

@babel/core
Babel本体の最新版
Babelは八百万のJavaScript構文を一定のバージョンと互換のある構文に変換するもの。
Nodeでは最新のJavaScript構文(import / exportなど含め)が動作しません。
そのため、Babelを使ってトランスパイルしてあげます。

babel-core@bridge
vue-jest@babel/coreではなく、babel-coreを参照してしまうらしく、これを解決するためにインストール。
Babel 7.x系だけど名前はbabel-coreなBabel本体。

@babel/preset-env
山ほどあるBabelの構文変換に関わるライブラリをいい感じに自動的に使ってくれるもの。
参考 : babel-preset-envを簡単にさわってみた。 - Qiita

vue-jest
vueをjestでテストできるようにするもの

@vue/test-utils
Vueのテストを書きやすくしてくれるユーティリティ

Babelのバージョンに注意

Babel 7.xからプラグインのプレフィックスとして@babel/がつくようになりました。
6.x以前のプラグインを使うとうまく動かない事があるらしい

設定ファイルをつくる

babel.config.js (.babelrc)

Babelの設定ファイルです。
babel.config.jsでも.babelrcでもいいのでソースルートに配置します。おそらく両方あるのはよろしく無いのでどちらか片方にしましょう。

babel.config.js
module.exports = {
    presets: [
        ['@babel/preset-env', {modules: false}]
    ],
    env: {
        test: {
            presets: [
                ['@babel/preset-env', {targets: {node: 'current'}}]
            ]
        }
    }
};

jest.config.js

どんなファイル名のものをテスト対象とするか、どのファイル名をどのモジュールで変換するか、などを設定できます。

jest.config.js
module.exports = {
    transform: {
        '.*\\.(vue)$': '<rootDir>/node_modules/vue-jest',
        '^.+\\.js$': '<rootDir>/node_modules/babel-jest'
    },
    moduleFileExtensions: [
        'js',
        'vue'
    ],
};

package.json (既存のものを編集)

Jestの起動コマンドを書き足します。
NODE_ENV=testとすることでNodeへテスト環境であることを明示しています。

package.json
{
    "private": true,
    "scripts": {
        "dev": "npm run development",
        "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
        "watch": "npm run development -- --watch",
        ... ,
        "test": "NODE_ENV=test jest"  <-追記
    },
    "devDependencies": { ... },
    ...
}

テストを書く

テストケースを作ってみましょう。

こんなファイルをテスト対象にしてみました。
カリー化してある2つの数字を足すだけの関数です。

ExampleSum.js
export default{
    sum(x){
        return (y){
            return x + y;
        }
    }
}

これをテストするスクリプトはこんな感じ。

example.test.js
import ExampleSum from "path/to/ExampleSum";

test('test sum()', ()=>{
    expect(ExampleSum.sum(1)(2)).toBe(3);
}

実行してみよう

npm testとターミナルへタイプしてJestを動かしてみよう。
--でファイル名を連結することでそのファイル名と部分一致するファイルのみをテスト対象としてくれます。

npm test -- example.test.js

そのほかのCLIオプションは Jest CLI Options · Jest へ。

async/awaitもテストできる

PromiseExample.js
export default {
    sleep() {
        return new Promise(resolve => {
            setTimeout(() => {
                resolve();
            }, 500);
        });
    }
}
test('test async', async () => {
    await PromiseExemple.sleep();
    expect(true).toBe(true);
});

Vueのフロントエンドテストもかけます

ガイド | Vue Test Utils

ExampleComponent.vue
<template>

</template>

<script>
    export default {
        name: "ExampleComponent",
        methods: {
            sum(x, y) {
                return x + y;
            }
        }
    }
</script>

<style scoped>

</style>
component.test.js
import ExampleComponent from "./models/ExampleComponent";

const {mount} = require("@vue/test-utils");

test('Vue component test', () => {
    const component = mount(ExampleComponent);
    expect(component.isVueInstance()).toBeTruthy();
    expect(component.vm.sum(1, 2)).toBe(3);
});

component.vmが僕らのよく知るVueコンポーネントインスタンスです。
DOMを操作してフォーム入力をしたり、クリックしたりもできます。


@babel/preset-envがびっくりするほど便利だったことがわかった。