【jasmine + Karma】 による javascript 単体テストをしてみた

javascript の テストフレームワーク「jasmine」の導入と簡単な使い方についてまとめていきます。
karmaで使用するブラウザはphantomjsを使用します。


# 事前作業

jasmine や karma など必要なライブラリをinstall します。
package.json の devDependecies に 下記を追加し、npm install を行います。

```pacage.json
"devDependencies": {
    "jasmine": "^2.5.2",
    "karma": "^1.3.0",
    "karma-coverage": "^1.1.1",
    "karma-jasmine": "^1.1.0",
    "karma-phantomjs-launcher": "^1.0.2",
    "karma-spec-reporter": "0.0.26",
    "phantomjs-prebuilt": "^2.1.14"
  }
```

テスト実施後にcoverageも見れるようにしたいので、「karma-coverage」を。
デフォルトのコンソールは見づらいため、「karma-spec-reporter」でコンソール表示を変更します。


# karma.conf.js の作成

karma init で作成されるkarma.conf.js を下記のように編集します。

```karma.conf.js
module.exports = function(config) {
  config.set({
    basePath: '',
    frameworks: ['jasmine'],
    files: [
      "src/script/js/*.js",
      "spec/*.js"
    ],
    exclude: [],
    preprocessors: {
      'src/script/js/*.js': ['coverage']
    },
    reporters: ['spec', 'coverage'],
    port: 9876,
    colors: true,
    logLevel: config.LOG_INFO,
    autoWatch: true,
    browsers: ['PhantomJS'],
    singleRun: false,
    concurrency: Infinity
  })
}
```

coverageの対象となるファイルは、preprocessors に記述し、reportersに、coverageを追加しています。
また、コンソールの表記を見やすくするため、reporters の progress を specに変更しています。

```
preprocessors: {
  'src/script/js/*.js': ['coverage']
},
```

```karma.conf.js
- reporters: ['progress'],
+ reporters: ['spec', 'coverage'],
```

# jasmine 単体テスト作成

テスト対象のjs は、demo.js とし、objectの値をテストしてみたいと思います。
テストファイルは、demoSpec.jsとし、demo.jsのtestTargetのnameの値についてテストを行います。

```demo.js
var testTarget = {};
testTarget.name = "jasmine-test";
```

```demoSpec.js
describe("demoTest", function() {
    it("demo getName", function() {
        expect(testTarget.name).toEqual("jasmine-test");
    })
});
```


# テスト実行

karma.conf.js と同階層で、下記を実行することで、karmaが実行されます。
オプション --single-run をつけない場合は、karmaのWebServerが起動し続け、常にソースを監視し変更があればテストを自動で回す形になります。

```
$ node_modules/karma/bin/karma --single-run 
```

ただ、これだと、pathを打つのも面倒なので、package.jsonにscriptとして追加します。

```package.json
"scripts": {
  "test": "npm run deleteCoverage && npm run karma",
  "karma": "karma start --single-run",
  "deleteCoverage": "rm -rf coverage/",
  "clean": "rm -rf node_modules/ && npm cache clean"
},
```

script を追記した後は、

```
$ npm test
```

で、karmaが走ります。

### テスト結果

```
$ npm test

  demoTest
    ✓ demo getName

PhantomJS 2.1.1 (Mac OS X 0.0.0): Executed 1 of 1 SUCCESS (0.004 secs / 0.002 secs)
TOTAL: 1 SUCCESS
```

テストが失敗した場合

```
$ npm test

demoTest
    ✗ demo getName
	Expected 'jasmine-test' to equal 'jasmine-testttt'.
	spec/demoSpec.js:3:40
	loaded@http://localhost:9876/context.js:151:17


PhantomJS 2.1.1 (Mac OS X 0.0.0): Executed 1 of 1 (1 FAILED) ERROR (0.004 secs / 0.002 secs)
```

## coverage
カバレッジは、Coverage > PhantomJs > index.html
とhtmlファイルで吐き出されます。

![coverage.png](https://qiita-image-store.s3.amazonaws.com/0/50028/2489499e-7f03-c015-c0a9-157692e581ef.png)


# おわりに

jasmineとkarma での単体テストの書き方はわかったので、次はAngularの単体テストをjasmineで書いてみようとおもう。

今回のソースは、下記URLから見れます。
https://github.com/yohei-takara/jasmine-karma

# 2017/01/03 追記

Angularの単体テストについてjasmineで行っってみたのを公開しました。
[【jasmine + Karma】 による AngularJs 単体テストをしてみた](http://qiita.com/TKR/items/95d0cb2849a57cbf4a60)