Kotest
を使用してkotlinプロジェクトのテストを行います。
#準備
gradleプロジェクトであれば、以下の依存関係を追加します。
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
//ここから
testImplementation 'io.kotest:kotest-runner-junit5:4.3.1' // for kotest framework
testImplementation 'io.kotest:kotest-assertions-core:4.3.1' // for kotest core jvm assertions
testImplementation 'io.kotest:kotest-property:4.3.1' // for kotest property test
//↑ここまでがKotestの依存関係
testCompile group: 'junit', name: 'junit', version: '4.12'
}
また、intelliJ IDEAを使用してテストする場合、このプラグインを使用することでテストが実行しやすくなります。
#テスト対象クラス
今回は、kotestを使用したテストがどんなものなのか雰囲気だけ掴んでいただければ良いので、ごく簡単な計算用クラスをテスト対象とします。
class Calc {
fun plus(a: Int, b: Int): Int {
return a + b
}
fun devide(a: Int, b: Int): Int {
return a / b
}
}
#テストコード
テストしたい処理にしたがって、一つずつ書いていきます。
##テストコードを書くにあたって - StringSpecを使用したテスト
本稿ではテストコードをStringSpec
を使用するスタイルで記述していきます。
Kotest
では、テストクラスがどのSpec
を継承するかで、テストの記述スタイルが異なります。他にもWordSpec
やFunSpec
、ShouldSpec
などがあります。各Specの差異は公式ページが参考になりますので、解説は省略します。(私見ですが、初めはStringSpec
を使えれば十分なのではないかと思います。)
##テストクラス
テスト対象クラスは以下のように記述します。前述の通りSpecによって書き方が異なりますが、StringSpec
では以下の2つの書き方があります。
//StringSpecのコンストラクタにラムダを渡す書き方
class CalcTest : StringSpec({
//ここにテストを書く
})
//initブロックを使用した書き方
class CalcTest : StringSpec(){
init {
//ここにテストを書く
}
}
どちらで書くかは個人・チームの好きにして良いと思います。本稿ではコンストラクタにラムダを渡す書き方で統一します。
それでは実際のテストを書いていきます。
##基本のアサーション - shouldBe
以下のテストのように、shouldBe
を使用することで値の正当性を確かめることができます。
なお、StringSpec
を継承する場合、文字列でテスト内容を示し、{}
で囲った部分に実際のテストを記述するスタイルとなります。
class CalcTest : StringSpec({
"1 + 1は2" {
val calc = Calc()
calc.plus(1, 1) shouldBe 2
}
"10 + 3は13" {
val calc = Calc()
calc.plus(10, 3) shouldBe 13
}
})
また、shouldBe
のように「値がそうなっているべき」の逆を表すshouldNotBe
もあります。こちらを使用する場合はメソッド名の通り、引数に渡される値になっていない場合にテスト成功となります。
"1 + 4は4にならないこと" {
val calc = Calc()
calc.plus(1,4) shouldNotBe 4
}
##例外をテストする - shouldThrow
例外をテストする場合はshouldThrow
を使用します。
"0で割った場合にExceptionとなること" {
val calc = Calc()
shouldThrow<ArithmeticException> {
calc.devide(10, 0)
}
}
なお、shouldThrow
は発生した例外オブジェクトを戻り値とするため、以下のように例外オブジェクトに対するテストを書くこともできます。
val exception = shouldThrow<ArithmeticException> {
calc.devide(10, 0)
}
exception.message shouldBe "/ by zero"
ただし、shouldThrow
は指定した例外クラスもしくはそのサブクラスが投げられた場合にアサーションが成功になってしまう点に注意してください。特定の例外クラスが正確に投げられているかを確認する場合はshouldThrowExactly
を使用しましょう。
##終わりに
上記までで、Kotest
のはじめの一歩は十分かと思います。
他にもCostom Matcher
やSoft Assertions
など、Kotest
に備わっている機能はたくさんありますが、解説の続きは公式ドキュメントに譲ります。