Vue CLI を使わずに Vue のユニットテストを実行できるようにする

Vueのユニットテストを書こうと思い調べてみたが、ざっと読んだところ、Vue CLI の利用を前提にしている文書が多かった。
だが現実的には、何らかの理由で Vue CLI を使わない、使っていないというケースも多いはず。
そこで、Vue CLI を使わない環境でユニットテストを導入する方法を調べた。

テストフレームワークJestアサーションライブラリはpower-assertを導入する。

使っているライブラリのバージョンは以下。

  • @babel/core@7.1.6
  • @babel/preset-env@7.1.6
  • @vue/test-utils@1.0.0-beta.25
  • babel-core@7.0.0-bridge.0
  • babel-jest@23.6.0
  • babel-preset-power-assert@3.0.0
  • jest@23.6.0
  • power-assert@1.6.1
  • vue@2.5.17
  • vue-jest@3.0.0
  • vue-template-compiler@2.5.17

最低限のセットアップ

$ npm init -yでプロジェクトを開始し、以下のコマンドを実行して必要なライブラリをインストールする。
既にVueの開発を行っている場合はインストール済みのライブラリもあるだろうから、それは省く。

$ npm i vue
$ npm i -D jest vue-jest vue-template-compiler @vue/test-utils @babel/core babel-jest babel-core@7.0.0-bridge.0 @babel/preset-env

@vue/test-utilsは、Vue コンポーネントユニットテストを行うための公式ライブラリ。
shallowMountなどを使えるようになる。まだ詳しく調べていないが、React で言うところのenzymeのようなものだろうか。

vue-test-utils.vuejs.org

インストールが終わったら、package.jsonjestブロックを追加して、以下のように書く。

  "jest": {
    "transform": {
      "^.+\\.js$": "babel-jest",
      "^.+\\.vue$": "vue-jest"
    }
  },

それと、プロジェクト直下に.babelrcに作成してpresets@babel/preset-envを設定する。
既に開発を行っているなら.babelrcは作成済みの可能性が高いが、まっさらな状態から作るなら以下の内容になる。

{
  "presets": ["@babel/preset-env"]
}

これでユニットテストを実行する準備は出来たので、適当にテストを書いてみる。

まずはテスト対象のコンポーネント
src/App.vue

<template>
  <div>
    <p>{{ message }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: 'Hello Vue!',
    };
  },
};
</script>

次に、テストコード。
src/__tests__/App.test.js

import {shallowMount} from '@vue/test-utils';

import App from '../App.vue';

const assert = require('assert');

describe('test', () => {
  describe('Vue', () => {
    it('shallowMount', () => {
      const wrapper = shallowMount(App);
      assert.equal(wrapper.text(), 'Hello Vue!');
    });
  });
});

これで$ npx jestとすると、テストが実行される。

$ npx jest
 PASS  src/__tests__/App.test.js
  test
    Vue
      ✓ shallowMount (15ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        2.103s
Ran all test suites.

正しく動いているのが分かる。

power-assert を導入する

このままでも問題ないが、テスト失敗時のメッセージを分かりやすくするためpower-assertを導入する。

github.com

まずはインストール。

$ npm i -D power-assert babel-preset-power-assert

次に.babelrcを更新して、env.test.presetspower-assertを設定する。

{
  "presets": ["@babel/preset-env"],
  "env": {
    "test": {
      "presets": ["power-assert"]
    }
  }
}

これで、テストコードのなかでconst assert = require('assert');を実行したときに自動的にpower-assertが読み込まれる。

テストの内容をassert.equal(wrapper.text(), 'Hello')にしてわざと失敗させて確認してみる。

まずはpower-assertを使わないケース。

  ● test › Vue › shallowMount

    assert.equal(received, expected) or assert(received) 

    Expected value to be equal to:
      "Hello"
    Received:
      "Hello Vue!"

    Difference:

    - Expected
    + Received

    - Hello
    + Hello Vue!

       9 |     it('shallowMount', () => {
      10 |       const wrapper = shallowMount(App);
    > 11 |       assert.equal(wrapper.text(), 'Hello');
         |              ^
      12 |     });
      13 |   });
      14 | });

power-assertを使うと、上記の内容に加えて以下のメッセージが追加される。

    Message:
        # src/__tests__/App.test.js:11
      
      assert.equal(wrapper.text(), 'Hello')
                   |       |               
                   |       "Hello Vue!"    
                   VueWrapper{isFunctionalComponent:undefined,_emitted:#Object#,_emittedByOrder:#Array#}