Kotlin Spek 1.1.x の使いかた

Spek については、以前、簡単に紹介したものを投稿していました。
http://qiita.com/yo1000/items/9f7148505895fd1d6760

ところが、当時の Spek はまだ、バージョン 1.0 にも達していない状態で、今あらためて使ってみようと思うと、この記事のようにはいかなくなっていたので、改めてメモを残しておくことにします。

# 環境

- macOS Sierra 10.12.4
- Oracle JDK 1.8.0_121
- Apache Maven 3.3.9 (Maven Wrapper)
- Kotlin 1.1.2-2
- Spek 1.1.1 (**1.1.0 には不具合があるためバージョンに注意**)

```
$ ./mvnw -version
Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-11T01:41:47+09:00)
Maven home: /Users/yo1000/.m2/wrapper/dists/apache-maven-3.3.9-bin/2609u9g41na2l7ogackmif6fj2/apache-maven-3.3.9
Java version: 1.8.0_121, vendor: Oracle Corporation
Java home: /Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre
Default locale: ja_JP, platform encoding: UTF-8
OS name: "mac os x", version: "10.12.4", arch: "x86_64", family: "mac"

$ cat pom.xml | grep '<kotlin.version>'
        <kotlin.version>1.1.2-2</kotlin.version>
$ cat pom.xml | grep '<spek.version>'
        <spek.version>1.1.1</spek.version>
```

# 依存関係

`pom.xml` の記述だけ気にしておけば、あとはとくに問題にならないので、ほぼここだけでこの記事は終わってしまう。

```xml:pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <!-- 中略 -->

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <maven.compiler.source>1.6</maven.compiler.source>
        <maven.compiler.target>1.6</maven.compiler.target>
        <java.version>1.6</java.version>
        <kotlin.version>1.1.2-2</kotlin.version>
        <spek.version>1.1.1</spek.version>
        <junit.platform.version>1.0.0-M4</junit.platform.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-stdlib</artifactId>
            <version>${kotlin.version}</version>
        </dependency>

        <!-- Testing -->
        <dependency>
            <groupId>org.jetbrains.spek</groupId>
            <artifactId>spek-api</artifactId>
            <version>${spek.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.jetbrains.spek</groupId>
            <artifactId>spek-junit-platform-engine</artifactId>
            <version>${spek.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.platform</groupId>
            <artifactId>junit-platform-runner</artifactId>
            <version>${junit.platform.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
        <testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
        <plugins>
            <plugin>
                <artifactId>kotlin-maven-plugin</artifactId>
                <groupId>org.jetbrains.kotlin</groupId>
                <version>${kotlin.version}</version>
                <executions>
                    <execution>
                        <id>compile</id>
                        <phase>compile</phase>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>test-compile</id>
                        <phase>test-compile</phase>
                        <goals>
                            <goal>test-compile</goal>
                        </goals>
                    </execution>
                </executions>
                <dependencies>
                    <dependency>
                        <groupId>org.jetbrains.kotlin</groupId>
                        <artifactId>kotlin-maven-allopen</artifactId>
                        <version>${kotlin.version}</version>
                    </dependency>
                </dependencies>
            </plugin>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.19</version>
                <dependencies>
                    <dependency>
                        <groupId>org.junit.platform</groupId>
                        <artifactId>junit-platform-surefire-provider</artifactId>
                        <version>${junit.platform.version}</version>
                    </dependency>
                </dependencies>
                <configuration>
                    <includes>
                        <include>**/Test*.java</include>
                        <include>**/*Test.java</include>
                        <include>**/*Tests.java</include>
                        <include>**/*TestCase.java</include>
                        <include>**/Spec*.java</include>
                        <include>**/*Spec.java</include>
                        <include>**/*Specs.java</include>
                    </includes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
```

以上のような具合で、依存関係に以下を、

- org.jetbrains.spek:spek-api:1.1.1
- org.jetbrains.spek:spek-junit-platform-engine:1.1.1
- org.junit.platform:junit-platform-runner:1.0.0-M4

`maven-surefire-plugin` の依存関係に以下を追加する必要がある。

- org.junit.platform:junit-platform-surefire-provider:1.0.0-M4

# テストコード

テストコードの書き方は以前とほとんど変更されていない。
以下、簡単な例を挙げておく。

```kotlin:ExampleSpec.kt
import org.jetbrains.spek.api.Spek
import org.jetbrains.spek.api.dsl.given
import org.jetbrains.spek.api.dsl.it
import org.jetbrains.spek.api.dsl.on
import org.junit.Assert

object StringBuilderSpec : Spek({
    given("builder") {
        val builder = StringBuilder("Foo")

        on("append") {
            builder.append("Bar")

            it("should return the result of appending the arg") {
                Assert.assertEquals("FooBar", builder.toString())
            }
        }
    }
})
```

# テスト実行

テスト実行については、Maven や Gradle から実行する方法と、IntelliJ IDEA を使用している場合は、IDE から実行する方法の2種類がある。

## Maven からテスト実行

普段通りにやれば良い。

```
$ ./mvnw clean test -U

..

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running StringBuilderSpec
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0 sec - in StringBuilderSpec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 15.922 s
[INFO] Finished at: 2017-05-05T11:58:49+09:00
[INFO] Final Memory: 40M/635M
[INFO] ------------------------------------------------------------------------
```

## IntelliJ IDEA からテスト実行

Spek Plugin をインストールすると、[Run/Debug Configurations] で、Spek を選択できるようになる。インストール、構成は以下のように。

1. [IntelliJ IDEA] > [Preferences...] > [Plugins] > [Browse repositories...] > `Spek` を検索してインストール、IntelliJ IDEA を再起動する
2. [Run] > [Edit Configurations...] > (ダイアログ左上の [+] ボタン、または ⌘N) > `Spek` を選択
3. 対象のテスト、またはパッケージを選択して [OK]
4. [Run] > [Run '作成したテスト構成名'] または、⌃R で実行

<img width="825" alt="spek-1.png" src="https://qiita-image-store.s3.amazonaws.com/0/47993/38399b85-3806-5232-e907-0ae5b6955e33.png">

<img width="1072" alt="spek-2.png" src="https://qiita-image-store.s3.amazonaws.com/0/47993/ad986d05-f882-f966-fe7c-cb9ece34ae6e.png">

<img width="764" alt="spek-3.png" src="https://qiita-image-store.s3.amazonaws.com/0/47993/655597b9-e17e-0d29-7ce2-c58e9abae661.png">

# 参考

http://spekframework.org/docs/latest/
https://github.com/JetBrains/spek/issues/195