Chapter 05

5 テストツールの導入

槐ニア
槐ニア
2021.06.05に更新

5-1 テストツールの導入

今回、テストツールとして、jest及びCypressを導入する。
jestは単体テストのためのCypressはE2Eテストのためのツールとなる。

5-2 単体テストツール: jestの導入

まず、jestのインストール及びvue-cliのtestプラグインをインストールする。

yarn add -D jest ts-jest vue-jest@next @vue/cli-plugin-unit-jest@next @types/jest

上記のパッケージの概要は以下の通り

  • jest

単体テスト用ツール。

  • vue-jest

jestを.vueファイルに対して使用できるようにするためのパッケージ

  • ts-jest

jestを.tsファイルに対して使用できるようにするためのパッケージ

  • @vue/cli-plugin-unit-jest

jestをvue-cliで使用できるようにするためのプラグイン

  • @types/jest

jest用のTypeScript型定義パッケージ

これに加えて、packages.jsonを以下のように編集する。

packages.json(抜粋)
{
  ...,
  "scripts": {
    ...,
    "test:unit": "vue-cli-service test:unit"
  },
  ...
}

この状態で以下のコマンドを実行することによって、
jestを実行できるようになる。

yarn test:unit

ただし、testコードの設置場所を書いていないため、エラーが発生するはずである。
そのため、packages.jsonに追加で以下の設定を行う必要がある。

packages.json(抜粋)
{
  ...,
  "jest": {
    "preset": "@vue/cli-plugin-unit-jest/presets/typescript",
    "transform": {
      "^.+\\.vue$": "vue-jest"
    }
  }
}

この設定により、vue用のプリセット設定と.vueファイルをvue-jestパッケージに渡すことができるようになる。
また、プラグインの仕様としてプロジェクト中の

  • **/tests/unit/**/*.spec.[jt]s?(x)
  • **/__tests__/*.[jt]s?(x)

に一致するファイルからテストを抽出し、実行することになる。

5-3 E2Eテストツール: Cypressの導入

次に以下のコマンドを実行することで、Cypressのインストールを行う。

yarn add -D @vue/cli-plugin-e2e-cypress

Cypressの設定のため以下のファイルを作成する。

  • cypress.json
  • tests/e2e/plugin/index.js
  • tests/e2e/support/index.js
  • tests/e2e/support/command.js

※tests配下のファイルに関しては、Cypressが本来自動的に生成するものである。
そのため、詳細な使用方法に関しては、Cypressのドキュメントを参照してほしい。

cypress.json
{
  "pluginsFile": "tests/e2e/plugins/index.js"
}
tests/e2e/plugin/index.js
	/* eslint-disable arrow-body-style */
	// https://docs.cypress.io/guides/guides/plugins-guide.html

	// if you need a custom webpack configuration you can uncomment the following import
	// and then use the `file:preprocessor` event
	// as explained in the cypress docs
	// https://docs.cypress.io/api/plugins/preprocessors-api.html#Examples

	// /* eslint-disable import/no-extraneous-dependencies, global-require */
	// const webpack = require('@cypress/webpack-preprocessor')

	module.exports = (on, config) => {
	  // on('file:preprocessor', webpack({
	  //  webpackOptions: require('@vue/cli-service/webpack.config'),
	  //  watchOptions: {}
	  // }))

	  return Object.assign({}, config, {
	    fixturesFolder: 'tests/e2e/fixtures',
	    integrationFolder: 'tests/e2e/specs',
	    screenshotsFolder: 'tests/e2e/screenshots',
	    videosFolder: 'tests/e2e/videos',
	    supportFile: 'tests/e2e/support/index.js'
	  })
	}
tests/e2e/support/index.js
// ***********************************************************
// This example support/index.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************

// Import commands.js using ES2015 syntax:
import "./commands";

// Alternatively you can use CommonJS syntax:
// require('./commands')

tests/e2e/support/command.js
// ***********************************************
// This example commands.js shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add("login", (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This is will overwrite an existing command --
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })

この状態で、e2eテスト実行用のスクリプトをpackages.jsonに追加する。

packages.json(抜粋)
{
  ...,
  "scripts": {
    ...,
    "test:e2e": "vue-cli-service test:e2e"
  },
  ...
}

また、テストコードを配置するためのディレクトリを作成する。

mkdir -p tests/e2e/plugins/specs

※これを行わないと、cypressが無限にspecsディレクトリを探しに行ってしまうため。

この状態で以下のコマンドを実行することでテストを行うことができる。

yarn test:e2e

5-4 packages.jsonのスクリプトの統合

今回のテストスクリプトは

  • test:unit
  • test:e2e

が別々に定義されており、それぞれ実行することができる。
yarnには(npmでも同じことができる)これを一度に実行する方法が用意されている。
実行するには、packages.jsonに以下の行を追加する。

{
  ...,
  "scripts": {
    ...,
    "test:e2e": "run-p test:*"
  },
  ...
}

こうすることで、
test:
というプレフィックスがついているすべてのスクリプトを実行することが可能になる。
ただし、この実行には
yarn-run-allというパッケージが必要になる。
これの導入はグローバルにインストールするべきかローカルにインストールするべきか、色々意見はあると思うので
必要である。
ということ以外はここでは触れない。

5-5 テストコード用リントの設定

この設定をすると、現状のESLintの設定だと、テストコードに対してプロダクションコードと同様のリントを行うことになってしまう。
今回は、別のリント設定を使用したいため.eslintrc.jsの設定を変更する。

.eslintrc.js(抜粋)
module.exports = {
  ...,
  overrides: [
    {
      files: [
        '**/__tests__/*.{j,t}s?(x)',
        '**/tests/unit/**/*.spec.{j,t}s?(x)'
      ],
      env: {
        jest: true
      }
    },
    {
      plugins: ['cypress'],
      files: ['**/tests/unit/**/*.{j,t}s?(x)'],
      env: {
        mocha: true,
        'cypress/globals': true
      },
      rules: {
        strict: 'off'
      }
    }
  ]
}

これで、テスト用のディレクトリ配下では、jest及び、Cypressを対象としたリントを行うことが可能になる。