目次
- この記事の目的
- テスト対象のコードを準備する
- karmaとbabel, webpack
- karmaでカバレッジを測定する
- テストを実行します
- まとめ
1. この記事の目的
最近、babel, webpackを使っていてkarmaでテストを書いています。
カバレッジの測定をしたくてkarma-coverageを使ってあれこれしていました。
しかしどうも依存するライブラリまでカバレッジ対象になってしまいます。
そこで今回はistanbulを使った解決策を紹介します。
2. テスト対象のコードを準備する
今回はthree.jsに依存するCanvasController.jsを準備します。
最終的に、このCanvasController.jsをテストするコードを書き、three.jsを除いたカバレッジを計測します。
まずは、必要なパッケージを導入します。
yarn add three yarn add --dev \ babel-core \ babel-loader \ babel-preset-es2015 \ babel-preset-es2016 \ webpack
次にwebpackの設定ファイルを準備します。
module.exports = { context: __dirname + '/src', entry: { 'application': './application', }, output: { path: __dirname + '/dist', filename: 'app.js' }, module: { loaders: [ { test: /\.js$/, exclude: /node_modules/, loader: "babel-loader", query:{ presets: ['es2015', 'es2016'] } } ] } };
次にエントリーポイントのsrc/application.jsを次のように保存します。
export { default as CanvasController } from './CanvasController';
次にsrc/CanvasController.jsを下記の通り保存します。
import * as THREE from 'three'; export default class CanvasController { constructor(canvasId) { let canvas = document.getElementById(canvasId); let renderer = new THREE.WebGLRenderer({canvas}); } }
これで、canvasのHTML要素を探して、three.jsのWebGLRendererを初期化するコードができました。
ではこれからはkarmaを使って、このCanvasController.jsをテストしていきます。
しかし、three.jsはカバレッジの対象外にするようにしていきます。
3. karmaとbabel, webpack
まず前提として、karmaでテストを実行するには、テストコードとテスト対象のコードがes5のJSである必要があります。
しかし、babelを使ってes2016などの記法で開発を進めている方も多いかと思います。
そこで、preprocessorという仕組みを使って、テスト実行前の処理を指定します。
今回はwebpackをpreprocessorとすることで、テストができるようにします。
この際のwebpackのloaderにbabelを指定することで、es2016->es5に変換してからwebpackに渡します。
webpackが最終的に1つのファイルにまとめたものをkarmaに渡し、テストを実行します。
まずは必要なパッケージを導入しましょう。 \
yarn add --dev \ assert \ karma \ karma-chrome-launcher \ karma-mocha \ karma-webpack \ mocha
次にkarmaの設定ファイルkarma.conf.jsを次のように保存します。
module.exports = function(config) { config.set({ frameworks: ['mocha'], browsers: ['Chrome'], singleRun: true, logLevel: config.LOG_INFO, plugins: [ 'karma-chrome-launcher', 'karma-mocha', 'karma-webpack' ], files: [ './test/**/*.js' ], preprocessors: { './test/**/*.js': ['webpack'] }, webpack: { module: { loaders: [ { loader: 'babel-loader', exclude: /node_modules/, query: { presets: ['es2015', 'es2016'] } } ] } }, }); };
これで、babel -> webpack -> karmaという順番でテスト実行できるようになりました。
次にテストコードを書きます。test/CanvasController.karma.jsを次の通り保存します。
import assert from 'assert'; import CanvasController from '../src/CanvasController'; describe('CanvasController', () => { describe('constructor', () => { it('no throw', () => { let canvas = document.createElement('canvas'); canvas.id = 'canvas'; document.body.appendChild(canvas); let canvasController = new CanvasController('canvas'); }); }); });
今回はカバレッジが本質なのでテストコードの書き方については省略します。
この状態でpackage.jsonのscripts.test: “karma start"として、yarn testを実行するとテストが走るはずです。
4. karmaでカバレッジを測定する
karmaでカバレッジを測定するために下記のパッケージを導入していきます。
- istanbul-instrumenter-loader
- 渡されたコードにinstrumentを仕込むローダー
- instrument: その場所をテスト実行時に通ったか測定するセンサー
- karma-coverage-istanbul-reporter
- テスト実行してカバレッジをまとめて出力する
実際にパッケージを導入するコマンドは下記の通りです。
yarn add --dev \ istanbul-instrumenter-loader \ karma-coverage-istanbul-reporter
次にkarmaの設定ファイルkarma.conf.jsを修正します。
module.exports = function(config) { config.set({ ... plugins: [ 'karma-chrome-launcher', 'karma-coverage-istanbul-reporter', 'karma-mocha', 'karma-webpack', 'istanbul-instrumenter-loader' ], ... webpack: { module: { loaders: [ { loader: 'babel-loader', exclude: /node_modules/, query: { presets: ['es2015', 'es2016'] } }, { loader: 'istanbul-instrumenter-loader', exclude: /node_modules/, include: /src/, enforce: 'post' } ] } }, reporters: ['progress', 'coverage-istanbul'], coverageIstanbulReporter: { reports: ['text-summary'] } }); };
修正したことは下記の通りです。
- pluginsを追加
- loadersにistanbul-instrumenter-loaderを追加
- node_modulesを除外してsrc配下のソースのみ測定対象にします
- enforce: ‘post'としてbabelより後になるようにしています
- このローダーもes5のjsファイルにのみ対応していたはず
- reportersにistanbulを追加
- text-summaryの形式でカバレッジを出力します
5. テストを実行します
yarn testを実行すると、テストが実行され、カバレッジが出力されます。
6. まとめ
今回はbabel, webpack, karmaを使ってテストのカバレッジを測定する方法を紹介しました。
ポイントはistanbul-instrumenter-loaderでnode_modulesをカバレッジ測定対象外にしている点です。
さて、これでブラウザでテストが動きますし、カバレッジも測定できます。
テストを書きつつモダンな環境でどんどん開発していきましょう。