パステル色な日々

気ままに綴るブログ

AngularJSのテストでカバレッジを計測する

おはこんばんちは、pastelIncです。
AngularJSのテストといえばKarmaを使う方も多いと思います。
その設定に少しハマったので今日は忘備録的な何かを残しておきます。

依存モジュールの紹介

$ npm i -D angular-mocks karma karma-mocha karma-browserify babelify power-assert babel-plugin-espower browserify-istanbul browserify karma-mocha-reporter mocha karma-coverage babel-preset-es2015 phantomjs-prebuilt karma-phantomjs-launcher isparta

なかなかの多さです。
babel-preset-es2015とか知りませんでした。未だbabel5しか使ってないのです。
presetを使うには設定の必要があるようでpackage.jsonにこのように書きました。

{
  ...
  "babel": {
    "presets": [
      "es2015"
    ]
  },
  ...
}

karmaの設定

karma.conf.jsを書きます。

module.exports = function(config) {
  config.set({
    basePath  : '',
    frameworks: ['mocha', 'browserify'],
    files     : [
      'test/**/*.test.js',
    ],
    exclude: [
      '**/*.swp',
    ],
    preprocessors: {
      'test/**/*.test.js': 'browserify',
    },
    browserify: {
      debug    : true,
      transform: [
        [
          'babelify', {
            plugins: ['babel-plugin-espower'],
          },
        ],
        [
          'browserify-istanbul',
          {
            instrumenter      : require('isparta'),
            instrumenterConfig: {
              embedSource: false,
            },
          },
        ],
      ],
    },
    reporters       : ['mocha', 'coverage'],
    coverageReporter: {
      dir      : 'coverage/',
      reporters: [
        { type: 'html' },
        { type: 'text' },
        { type: 'lcov' },
      ],
    },
    port       : 9876,
    colors     : true,
    logLevel   : config.LOG_INFO,
    autoWatch  : true,
    browsers   : ['PhantomJS'],
    singleRun  : false,
    concurrency: Infinity,
  });
};

僕はソースコードもテストコードもbabelを使って書くので、
両方に対してbrowserifyをpreprocessorsとして設定しています。
angular-mocksとかはテストコードに直にimportするスタイルなので、
ここではfilesの中に含めてません。

embedSourceの設定をtrueにすることで、
トランスパイル済みのコードをカバレッジの結果に出力することができます。

この辺を参考ください、経緯を追うことができます。

テストを行う

ソースコードです。

import angular from 'angular';

const modName = 'app.components.main';

class MainComponent {
  constructor() {
    this.name = 'Angular1.5';
  }
}

angular.module(modName, []).component('main', {
  controller: MainComponent,
  template  : '<h1>Hello {{$ctrl.name}}</h1>'
});

export default modName;

テストコードです。

import assert from 'power-assert';
import 'angular-mocks';
import mainModule from '../src/components/main';

describe('MainComponent', () => {
  let  component, scope;

  beforeEach(angular.mock.module(mainModule));

  beforeEach(inject(($rootScope, $componentController) => {
    scope = $rootScope.$new();
    component = $componentController('main', {$scope: scope});
  }));

  it('should be had name', () => {
    assert(component.name === 'Angular1.5');
  });
});

Angular1.5がめでたくリリースされました。
せっかくなのでcomponentメソッドを使ってみたソースをテストしています。
componentはdirectiveでかくよりもいろいろ書式を省略できます。

directiveのテストはcustom elementを$compileした結果からcontrollerを取得していました。

参考

componentをテストするときには$componentControllerを使って簡易に書くことができます。

あとがき

AngularJSのテストの記事をあまり見かけないので書いてみました。
依存モジュールが多くて何が何をしているのか把握するのが大変でしたが、
初めてカバレッジを使ってテストコードをかけるようになりました。
AngularJS1.5もリリースされてAngular2への移行準備がはじまったなという感じがします。
着々と進めていきましょう。ではまたねヽ( ´ー`)ノ