Karmaを試してみる

http://karma-runner.github.io/0.12/index.html
今回はKarmaに手を出したいと思います。
まずはKarmaについてです。簡単に言うとテスト駆動開発用のテストランナーです。
#About Karma
* Karmaのゴールは、製品のテスト環境を提供することである。
* その環境は開発者がコーディングに集中でき、簡単にテスト結果をえられるものである。
* 高速なフィードバックこそが生産性と創造性をつくりあげる。

##Test Real device
* 携帯やタブレット、実際のブラウザ上で動作する
* a headless PhantomJS instanceを使用する

##Remote Control
* コマンドラインやIDEからワークフロー全体を制御できる
* ファイルの保存をトリガーにKarmaはテストを実行する

##Testing Framework Agnostic
*  Jasmine, Mocha, QUnit などでテストを記述できる
*  アダプタを用意することで他のフレームワークも使用可能

##Open Source
* GitHubのOSSコミュニティでKarmaの開発とメンテナンスができる

##Easy Debugging
* WebStorm経由のIDEかGoogle Chromeで容易にデバッグができる

##Continuous Integration
*  Jenkins, Travis, Semaphoreなどと併用し継続的インテグレーションが可能である

#Installation
Karma本体とjasmineとchromeのpluginを導入します。
* Node.js/npmを使用する
* `npm install karma --save-dev`
* `npm install karma-jasmine karma-chrome-launcher --save-dev`

つぎにコマンドラインツールをインストールします。
`npm install -g karma-cli`
これでkarmaコマンドが使えるようになりました。

```
C:\workspace\karma>karma --version
Karma version: 0.12.31
```
#Configuration
* Karmaの使用にはコンフィグファイルが必要
* `karma init <filename>.js`で作成する

なお今回はtestフォルダにテストファイル(test.js)とテスト対象ファイル（app.js)を置くことにしました。

```
C:\workspace\karma>karma init my.conf.js

Which testing framework do you want to use ?
Press tab to list possible options. Enter to move to the next question.
> jasmine

Do you want to use Require.js ?
This will add Require.js plugin.
Press tab to list possible options. Enter to move to the next question.
> no

Do you want to capture any browsers automatically ?
Press tab to list possible options. Enter empty string to move to the next quest
ion.
> Chrome
>

What is the location of your source and test files ?
You can use glob patterns, eg. "js/*.js" or "test/**/*Spec.js".
Enter empty string to move to the next question.
> test/**/*.js
WARN [init]: There is no file matching this pattern.

>

Should any of the files included by the previous patterns be excluded ?
You can use glob patterns, eg. "**/*.swp".
Enter empty string to move to the next question.
>

Do you want Karma to watch all the files and run the tests on change ?
Press tab to list possible options.
> yes


Config file generated at "C:\workspace\karma\my.conf.js".


C:\workspace\karma>
```

Karmaを実行します。デフォルトではkarma.conf.jsを見に行くそうです。
`karma start <filename>.js`

```
C:\workspace\karma>karma start my.conf.js
WARN [karma]: Port 9876 in use
INFO [karma]: Karma v0.12.31 server started at http://localhost:9877/
INFO [launcher]: Starting browser Chrome
INFO [Chrome 41.0.2272 (Windows 8.1)]: Connected on socket ThTPTW8AQFf7dPqi0xzr
with id 7570168
Chrome 41.0.2272 (Windows 8.1): Executed 0 of 0 ERROR (0.003 secs / 0 secs)
```

うまくいくとブラウザが開き、コンソールにテスト結果が表示されます。今はテストがないので０件です。なおブラウザにはテスト結果は表示されません。ご注意ください。
![image](https://qiita-image-store.s3.amazonaws.com/0/71988/a77601cf-8ae1-2a25-84ee-89361b75c3f4.png)

ではapp.jsとtest.jsを作成します。

```test/app.js(失敗ケース）
var Counter = function(){
	this.x = 0;
}

Counter.prototype.count = function() {
	this.x += 2;
};
```

```test/test.js
describe("A suite", function() {
  it("contains spec with an expectation", function() {
  	c = new Counter();
  	c.count();
  	c.count();
  	c.count();
	expect(3).toBe(c.x);
  });
});
```

実行結果はつぎのようになります。
３が欲しいところで６になっているので失敗です。

```
Chrome 41.0.2272 (Windows 8.1) A suite contains spec with an expectation FAILED
        Expected 6 to be 3.
            at Object.<anonymous> (C:/workspace/karma/test/test.js:7:14)
Chrome 41.0.2272 (Windows 8.1): Executed 1 of 1 (1 FAILED) (0 secs / 0.004 secs)
Chrome 41.0.2272 (Windows 8.1): Executed 1 of 1 (1 FAILED) ERROR (0.01 secs / 0.
004 secs)
```

#Debugger
せっかくですのでデバッガを使ってみたいと思います。ブラウザにDEBUGボタンがありますが、使い方がいまいちわかりませんでしたので、別の方法を使います。
まずブラウザ上でF12を押しデバッグモードにします。

```test/test.js
describe("A suite", function() {
  it("contains spec with an expectation", function() {
  	c = new Counter();
  	debugger;
  	c.count();
  	c.count();
  	c.count();
	expect(c.x).toBe(3);
  });
});
```
そして上のように止めたい位置に`debugger;`を差し込みます。そうしますと該当位置でブラウザのデバッガが止まります。はい、あとはステップ実行すればカウンターが２づつ増えているのがわかりますので、app.jsを直します。
![image](https://qiita-image-store.s3.amazonaws.com/0/71988/3accb441-44b2-2bb0-3aa3-55033fd72532.png)

```test/app.js(成功ケース）
var Counter = function(){
	this.x = 0;
}

Counter.prototype.count = function() {
	this.x += 1;
};
```

実行結果

```
Chrome 41.0.2272 (Windows 8.1): Executed 1 of 1 SUCCESS (0.006 secs / 0.002 secs)
```

無事、テスト駆動開発もどきができました。
たぶんテストが失敗した場合になんらかのアクションをフックできると思うんで、今度やってみたいと思います。