KotlinのテストをSpekで書いてwerckerでテストしてみる

最近話題のKotlin。せっかくならテストとCIをいい感じにやりたい :innocent: 
ということで今回は、[Spek](http://spekframework.org)でテストコードを書いて、[wercker](http://www.wercker.com/)でCIするところまで試してみました。
どちらも使うのは初めてなので、バリバリで使っている方からは物足りない記事になってます...

※確認に使ったGitHubリポジトリは[コチラ](https://github.com/MiyamotoTa/spek_wercker)です。

# Spekでテストを書く

## Spekとは？
SpekはKotlinの開発元であるJetBrainsが開発しているテスティングフレームワークです。
`describe`や`it`といったワードを使うことでRSpecのような記述ができるのが特徴です。

## テストの書き方
Spekのテストコードは

* given, on, it
* describe, it

の2種類の書き方ができます。

### given, on, it
Spekの初期バージョンの基礎になった書き方です。
オブジェクト宣言のSpekコンストラクタ内に以下のコンポーネントを記述します。

* given: テストの準備をするための箇所
* on: どのようなアクションをするのかを定義する箇所
* it: onで定義されたアクションを検証する箇所

コードは↓のような感じになります。

```kotlin:CalculatorSpec.kt
object CalculatorSpec: Spek({
    given("計算のテスト") {
        val calculator = SampleCalculator()
        on("足し算") {
            val sum = calculator.sum(2, 4)
            it("第一引数の数値と第二引数の数値を足した結果を返す") {
                assertEquals(6, sum)
            }
        }
        on("引き算") {
            val subtract = calculator.subtract(4, 2)
            it("第一引数の数値から第二引数の数値を引いた結果を返す") {
                assertEquals(2, subtract)
            }
        }
    }
})
```

### describe, it
JasmineやMochaスタイルの書き方をする書き方です。
`describe`のなかにテストを定義していきます。

このスタイルで必要なのは

* describe: どのようなテストなのかを定義する箇所
* it: onで定義されたアクションを検証する箇所

になります。
コードは↓のような感じになります。

```kotlin:SimpleSpec.kt
object SimpleSpec : Spek({
    describe("計算のテスト") {
        val calculator = SampleCalculator()

        on("足し算") {
            val sum = calculator.sum(2, 4)

            it("第一引数の数値と第二引数の数値を足した結果を返す") {
                assertEquals(6, sum)
            }
        }

        on("引き算") {
            val subtract = calculator.subtract(4, 2)

            it("第一引数の数値から第二引数の数値を引いた結果を返す") {
                assertEquals(2, subtract)
            }
        }
    }
})
```

## テストの実行(ローカル)
ローカルでテストを走らせるなら、`gradle test`をするだけでOKです。

# werckerでCIする
## werckerとは？
`wercker`はDockerコンテナベースのCIツールです。
werckerの世界では`step`という単位でコマンドをまとめ、それらのstepを`Build`や`Deploy`といったフェーズ別にまとめ実行していきます。 [※ How Wercker Works](http://blog.wercker.com/How-wercker-works)
これらの設定は`wercker.yml`に記述します。

## 事前準備
werckerの動きをローカルでも再現するために、[wercker-cli](http://www.wercker.com/cli)というものが用意されているので、これを事前にインストールしておきます。

## 定義ファイル作成
プロジェクトルートに`wercker.yml`という名前で、以下のような定義ファイルを準備します。
今回は`gradle test`したいだけなので、werckerが事前に用意してくれている[gradle用のstep](https://github.com/wercker/step-gradle)を使います。
もちろん自分で書いたコマンドをステップとすることも可能です。

```yaml:wercker.yml
box:
  id: openjdk

build:
  steps:
    - java/gradle:
      name: "spek_wercker test"
      task: test
      version: "4.4"
      cache_project_cache: true
```

## ローカルで実行

`wercker build`を実行するとopenjdkイメージをpullして`gradle test`コマンドを実行してくれます。
wercker-cliが問題なく動作したのでGitHubにpushしてしまいます。

## werckerでテストする
[wercker](https://app.wercker.com/)にログインし、 GitHubリポシトリを追加します。

### GitHub上で変更を検知してCIできるか確認してみる

テストコードに以下のコードを追加してGitHubにpushします。

```kotlin:CalcuratorSpec.kt
on("掛け算") {
    val multiplication = calculator.multiplication(4, 2)

    it("第一引数の数値と第二引数の数値の積を返す") {
        assertEquals(8, multiplication)
    }
}
```

```kotlin:SimpleSpec.kt
on("掛け算") {
    val multiplication = calculator.multiplication(4, 2)

    it("第一引数の数値と第二引数の数値の積を返す") {
        assertEquals(8, multiplication)
    }
}
```

```kotlin:SampleCalculator.kt
fun multiplication(a: Int, b: Int) = a + b
```

![MiyamotoTa spek_wercker   loading.png](https://qiita-image-store.s3.amazonaws.com/0/40456/20c63e29-746a-5317-21f7-b3857b4178d2.png)

無事に怒られました :innocent:
今回は`gradle test`だけでしたが、werckerには他にも色々なstepが用意されています。
これらのstepを組み合わせるだけでもいい感じに捗りそうな予感がしています。