mocha + webpack = mocha-loader が便利


※ Webpackを使って開発されている方向けです。

みなさんは、開発しながら同時にテストを流していますか?

mocha-loader

このローダをwebpackのConfigに追加するだけで、webpack-dev-serverで開発中や、ビルド時に自動でテストを流してくれます。
せっかく書いたテスト、流し忘れがなくなるのはいいことですよね。

代替フレームワーク

mocha-loader」個人的には好きなのですが、これから発展していくのかは微妙です。
一応、mocha + webpackなら他にもフレームワークがあります。

ちなみにmochapackは、mocha-webpackの更新が止まっているようなので、作ったらしいです。
ただ、webpack4との相性なのか、私の環境が悪かったのか、どちらもうまく動かなかったので、mocha-loaderを使いました。

では、使い方を説明していきます。

使い方

インストール

npm i -D mocha mocha-loader

この通り、mochaがインストールされてある必要があります。
逆に言えば、インストールされているmochaのバージョンが使われます。

設定

entrymoduleに設定を足すだけです。

entryには、テストファイルを指定します。
moduleで、mocha-loaderを読み込みます。

これだけです。

webpack.config.js
module.exports = {
  ...
  entry: [
    "test": [
      "./test/sample1.spec.js",
      "./test/sample2.spec.js",
    ]
  ]
  ...
  module: {
    rules: [
      {
        test: /spec\.js$/,
        use: {
          loader: "mocha-loader",
          options: {
             // mocha.setup(option)に渡すオプションが書ける
             // https://mochajs.org/#running-mocha-in-the-browser
          }
        },
        exclude: /node_modules/
      }
    ]
  }
}

テストのサンプルです。

sample1.spec.js
import { add } from "../src/index.js";

import chai from "chai";

chai.should();

describe("sample1 test", () => {
  it("add test", () => {
    add(1, 2).should.be.eqaul(3);
  });
});

テスト結果を確認する。

html-webpack-pluginを使います。

webpack.config.js
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
  ...

  plugins: [
    new HtmlWebpackPlugin({
      filename: "test.html",
      inject: "body",
      chunks: ["test"]
    })
  ]
}

ここを見ると分かりますが、テスト結果は、id=mochaの要素に入るので、HtmlWebpackPluginで、テンプレートを用いて埋め込むことも可能です。

webpackコマンドでビルドすることで、dist/test.htmlができ、そちらで結果が見れます。

上のサンプルだと、chaiのメソッド名が間違っています。
× eqaul
equal

ので、こんな結果が見れます。

CI

残念ながら、mocha-loaderはドキュメントが簡潔すぎてCIへの導入がよくわからないです。
なので、少々強引な方法ですが、test.htmlをスクレイピングすることで、エラーを集めることは可能です。

ここでは、puppeteerを使いました。

ci.js
const puppeteer = require("puppeteer");

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto(`file://${__dirname}/../dist/test.html`);

  await page.waitFor("#mocha-report");

  const error = await page.evaluate(() => {
    const errorElements = document.getElementsByClassName("error");

    return [...errorElements].map(x => x.innerText).join("\n\n");
  });

  await browser.close();

  if (error !== "") {
    console.error(error);

    process.exit(1);
  }
})();

まとめ

どうでしたでしょうか。
紹介した例はこちらのリポジトリに入れておきましたので、よかったら見てください。

mocha-loader-example