RailsのVue.jsをWebpackerとJestでテストする(翻訳)

概要

原著者の許諾を得て翻訳・公開いたします。

RailsのVue.jsをWebpackerとJestでテストする(翻訳)

今やっているプロジェクトで、既存のRailsアプリにVue.jsを統合する方法の調査をを命じられました。とりあえず公式ガイドを読み、チュートリアルを視聴し、ブログを読みまくった結果、Vueコンポーネントを完全に動かせるようになりました。

最後の段階でいくつかテストを書こうとしましたが、残念なことにWebpacker gemにはテスト向け設定が含まれていなかったので、自分で設定せざるを得ませんでした。

驚いたことに、満足な設定方法がドキュメントに見当たらなかったのです。そこで私が何とかこれを動かせるようにしたときの方法を本記事で皆様と共有したいと考えました。

1. Jestのインストール

特にこれといった好みもなかったので、Jestを使うことに決めました。vue-cliも同梱されていたので使いました。

Jestのインストールで必要なのは、プロジェクトのルートディレクトリでyarn add --dev jestを実行することだけです。続いて、package.jsonに自分のテストスクリプトを追加します。

{
  "scripts": {
    "test": "jest",
    ...
  },
  ...
}

これで、yarn testを実行すればテストが走ります。

2. テストの置き場所を定義する

この時点でyarn testを実行しようとすると、config/webpack/test.jsでコケます。これは、Jestがプロジェクト内のテストファイルを探索する方法が原因です。基本的にはプロジェクト全体のうち.spec.js.test.jsにマッチするすべてのファイルを実行します。ここではテストファイルが*.test.jsとマッチしたので、テストとして実行されようとしていたのです。

自分たちのテストを実行する基準を満たすプロジェクト内の他のファイルと同様、Webpack configファイルを使わないようにしたいので、探索するファイルの場所をJestに指定する必要があります。

ここではRspecを使っていることもあり、spec/javascriptsディレクトリを探索場所として指定することにしました。もちろん、自分のプロジェクトに合う場所を自由に指定することもできます。

これを行うには、package.jsonファイルにrootsを追加しなければなりません。

"jest": {
  "roots": [
    "spec/javascript"
  ]
},

package.jsonのサイズがかなり大きいのでこのファイルにこれ以上設定を追加したくない場合は、--config <path/to/js|json>オプションでJest設定を定義できます。この方法にする場合、package.jsonは次のような感じになるはずです。

  {
    "scripts": {
      "test": "jest --config spec/javascript/jest.conf.js",
      ...
    },
    ...
  }

これが動作することを確認するために、以下のようなシンプルなテストをspec/javascript/team.spec.jsファイルを作成してもよいでしょう。

test('there is no I in team', () => {
  expect('team').not.toMatch(/I/);
});

これで再びyarn testを実行すれば、greenの「PASS」が表示され、動作していることがわかるはずです。

3. babelをrescueする

最初のテストが動くようになったので、一歩進めてVueコンポーネントをテストしてみましょう。

最初にやってみるのは、たいていspec/javascript/の下にファイルを作成してmy_component.spec.jsのような名前を付けることでしょう。続いて次のようにimportステートメントで自分のコンポーネントをspecにインポートしてみましょう。

  import MyComponent from '../../app/javascript/my_component.vue';

これをやってみた方は、そのままyarn testでテストを実行してみてください。SyntaxError: Unexpected token importエラーが出力されます。

ここでの問題は、importがECMAScript 6の一部である点です。つまりBabelなどのトランスパイラの助けが必要になるということです。

動くようにするには、yarn add --dev babel-jest babel-preset-es2015で2つのパッケージをインストールし、.babelrcファイルにes2015プリセットを追加する必要があります。

{
  "presets": ["es2015",
    ["env", {
          ...

さらに一歩進めてみたい方は、moduleDirectoriespackage.jsonに追加すると、モジュールへのフルパスを入力しなくても済むようになります。

"jest": {
  ...
  "moduleDirectories": [
    "node_modules",
    "app/javascript"
  ]
}

これで、先ほどのパスを簡単にできます。

  import MyComponent from '../../app/javascript/my_component.vue';

上のパスは以下のように書けます。

  import MyComponent from 'my_component.vue';

4. Vueが見つからない

ここまでの手順をすべて行った場合、yarn testでテストを実行するとまたしてもSyntaxErrorが表示されます。これは、コンポーネントのimportは成功したものの、.vueファイルフォーマットを理解できていないためです。

幸い、この辺りの面倒を見てくれるvue-jestを使えます。早速yarn add --dev vue-jestを実行してvue-jestをインストールし、READMEの指示に沿ってmoduleFileExtensionstransformmapCoverageを追加します。追加後のpackage.jsonは次のような感じになるはずです。

"jest": {
  ...
  "moduleFileExtensions": [
    "js",
    "json",
    "vue"
  ],
  "transform": {
    "^.+\\.js$": "<rootDir>/node_modules/babel-jest",
    ".*\\.(vue)$": "<rootDir>/node_modules/vue-jest"
  },
  "mapCoverage": true
}

moduleFileExtensionsを使うと、単一のファイルコンポーネントのimport.vue拡張子が不要になります。

  import MyComponent from 'my_component.vue';

上のパスは、以下のように書き換えられます。

  import MyComponent from 'my_component';.

これで、importをシームレスに使えるようになりました。

transformセクションに記述されたルールでは、テストするファイルの変換を担当するパッケージを指定します。ここではすべての.vueファイルの扱いをvue-jestに任せたいので、これらのファイルはJestで扱われる前に純粋なJavaScriptに変換されます。

mapCoverageは、トランスフォーマーが生成するソースマップを使うために設定してあります。Jestはこのソースマップを用いて、カバレッジの試行や、レポート生成時や閾値チェック中に元のソースコードとのマッピングを行います。

最後に、Vue.js公式の単体テストユーティリティライブラリであるvue-test-utilsを追加しましょう。yarn add --dev @vue/test-utilsを実行するだけですぐ使えるようになります。

ついにVueコンポーネントのテストを書けるようになりました🎉。

クレジット

本記事は、Jest公式ドキュメントHow to setup JavaScript testing in Rails 5.1 with Webpacker and JestなどWeb上の多数のドキュメントから集めた情報を元に執筆いたしました。

関連記事

新しいRailsフロントエンド開発(1)Asset PipelineからWebpackへ(翻訳)

デザインも頼めるシステム開発会社をお探しならBPS株式会社までどうぞ 開発エンジニア積極採用中です! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

hachi8833

Twitter: @hachi8833、GitHub: @hachi8833 コボラー、ITコンサル、ローカライズ業界、Rails開発を経てTechRachoの編集・記事作成を担当。 これまでにRuby on Rails チュートリアル第2版の半分ほど、Railsガイドの初期翻訳ではほぼすべてを翻訳。その後も折に触れてそれぞれ一部を翻訳。 かと思うと、正規表現の粋を尽くした日本語エラーチェックサービス enno.jpを運営。 実は最近Go言語が好き。 仕事に関係ないすっとこブログ「あけてくれ」は2000年頃から多少の中断をはさんで継続、現在はnote.muに移転。

hachi8833の書いた記事

週刊Railsウォッチ

インフラ

ActiveSupport探訪シリーズ