Try KotlinTest

3be52a14c8c58209263d7f83204b8dc7?s=47 Rui Kowase
December 15, 2017

Try KotlinTest

Android Test Nightの資料です。

Android Test Night #2 - connpass
https://testnight.connpass.com/event/69397/

3be52a14c8c58209263d7f83204b8dc7?s=128

Rui Kowase

December 15, 2017
Tweet

Transcript

  1. Try KotlinTest Rui Kowase @rkowase

  2. 自己紹介 • 名前: 小和瀬 塁(こわせ るい) • アカウント: @rkowase 2

  3. 今日の話 https://github.com/kotlintest/kotlintest KotlinTest is a flexible and comprehensive testing tool

    for Kotlin.
  4. Assertion Lib (Test Framework) for Kotlin 名前 GitHub Star 簡単な説明

    spek 970 Spec風、Java 8 Only kotlintest 593 Spec風 expekt 96 メソッドチェーン記法、更新頻度低 Assertk 78 AssertJ風 knit 57 DroidKaigi 2017アプリで利用、更新頻度低 (2017/12/15時点)
  5. 導入(Gradle) testImplementation 'io.kotlintest:kotlintest:2.0.7'

  6. 基本的な使い方 // test cases in init block class MyTests :

    StringSpec() { init { // tests here } } // test cases in lambda expression class MyTests : StringSpec({ // tests here })
  7. 基本的な使い方 // test cases in init block class MyTests :

    StringSpec() { init { // tests here } } // test cases in lambda expression class MyTests : StringSpec({ // tests here })
  8. 基本的な使い方 // test cases in init block class MyTests :

    StringSpec() { init { // tests here } } // test cases in lambda expression class MyTests : StringSpec({ // tests here })
  9. 基本的な使い方 // test cases in init block class MyTests :

    StringSpec() { init { // tests here } } // test cases in lambda expression class MyTests : StringSpec({ // tests here })
  10. 色々なSpec Spec 簡単な説明 String Spec StringSpec reduces the syntax to

    the absolute minimum. Fun Spec FunSpec allows you to create tests similar to the junit style. Should Spec ShouldSpec is similar to fun spec, but uses the keyword should instead of test. Word Spec WordSpec uses the keyword should and uses that to nest test blocks after a context string. Feature Spec FeatureSpec allows you to use feature and scenario. Behavior Spec BehaviorSpec allows you to use given, when, then. Free Spec FreeSpec allows you to nest arbitary levels of depth using the keyword - (minus).
  11. String Spec class MyTests : StringSpec() { init { "strings.length

    should return size of string" { "hello".length shouldBe 5 } } }
  12. Word Spec class MyTests : WordSpec() { init { "String.length"

    should { "return the length of the string" { "sammy".length shouldBe 5 "".length shouldBe 0 } } } }
  13. Word Spec class MyTests : WordSpec() { init { "String.length"

    should { "return the length of the string" { "sammy".length shouldBe 5 "".length shouldBe 0 } } } }
  14. Feature Spec class MyTests : FeatureSpec() { init { feature("the

    thingy bob") { scenario("should explode when I touch it") { // test here } } } }
  15. Feature Spec class MyTests : FeatureSpec() { init { feature("the

    thingy bob") { scenario("should explode when I touch it") { // test here } } } }
  16. Behavior Spec class MyTests : BehaviorSpec() { init { given("a

    broomstick") { `when`("I sit on it") { then("I should be able to fly") { // test code } } } } }
  17. Behavior Spec class MyTests : BehaviorSpec() { init { given("a

    broomstick") { `when`("I sit on it") { then("I should be able to fly") { // test code } } } } }
  18. Free Spec class MyTests : FreeSpec() { init { "String.length"

    - { "should return the length of the string" { "sammy".length shouldBe 5 "".length shouldBe 0 } } } }
  19. Free Spec class MyTests : FreeSpec() { init { "String.length"

    - { "should return the length of the string" { "sammy".length shouldBe 5 "".length shouldBe 0 } } } }
  20. Intercepting a Test Case override fun interceptTestCase(context: TestCaseContext, test: ()

    -> Unit) { // before test() // don't forget to call test()! // after }
  21. Intercepting a Test Case override fun interceptTestCase(context: TestCaseContext, test: ()

    -> Unit) { // before test() // don't forget to call test()! // after } setUp()
  22. Intercepting a Test Case override fun interceptTestCase(context: TestCaseContext, test: ()

    -> Unit) { // before test() // don't forget to call test()! // after } tearDown()
  23. AndroidのPresenterのテストで使ってみる class StringSpecTest : StringSpec() { @Mock lateinit var mRepository:

    GitHubRepository @Mock lateinit var mView: GitHubContract.View lateinit var mPresenter: GitHubPresenter lateinit var mSchedulerProvider: BaseSchedulerProvider override fun interceptTestCase(context: TestCaseContext, test: () -> Unit) { MockitoAnnotations.initMocks(this) mSchedulerProvider = ImmediateSchedulerProvider() mPresenter = GitHubPresenter(mRepository, mView, mSchedulerProvider) test() // don't forget to call test()! }
  24. AndroidのPresenterのテストで使ってみる class StringSpecTest : StringSpec() { @Mock lateinit var mRepository:

    GitHubRepository @Mock lateinit var mView: GitHubContract.View lateinit var mPresenter: GitHubPresenter lateinit var mSchedulerProvider: BaseSchedulerProvider override fun interceptTestCase(context: TestCaseContext, test: () -> Unit) { MockitoAnnotations.initMocks(this) mSchedulerProvider = ImmediateSchedulerProvider() mPresenter = GitHubPresenter(mRepository, mView, mSchedulerProvider) test() // don't forget to call test()! }
  25. AndroidのPresenterのテストで使ってみる class StringSpecTest : StringSpec() { @Mock lateinit var mRepository:

    GitHubRepository @Mock lateinit var mView: GitHubContract.View lateinit var mPresenter: GitHubPresenter lateinit var mSchedulerProvider: BaseSchedulerProvider override fun interceptTestCase(context: TestCaseContext, test: () -> Unit) { MockitoAnnotations.initMocks(this) mSchedulerProvider = ImmediateSchedulerProvider() mPresenter = GitHubPresenter(mRepository, mView, mSchedulerProvider) test() // don't forget to call test()! }
  26. AndroidのPresenterのテストで使ってみる init { "Should init service when presenter started"{ mPresenter.start()

    verify(mRepository).initService() } "Should show error when request failed"{ Mockito.`when`(mRepository.request("")).thenRetrn(Observable.error(Exception()) mPresenter.request(GitHubPresenterTest.USER) verify(mView).showError() } }
  27. AndroidのPresenterのテストで使ってみる init { "Should init service when presenter started"{ mPresenter.start()

    verify(mRepository).initService() } "Should show error when request failed"{ Mockito.`when`(mRepository.request("")).thenRetrn(Observable.error(Exception()) mPresenter.request(GitHubPresenterTest.USER) verify(mView).showError() } }
  28. AndroidのPresenterのテストで使ってみる init { "Should init service when presenter started"{ mPresenter.start()

    verify(mRepository).initService() } "Should show error when request failed"{ Mockito.`when`(mRepository.request("")).thenRetrn(Observable.error(Exception()) mPresenter.request(GitHubPresenterTest.USER) verify(mView).showError() } }
  29. 問題点(気になるところ) • StringSpec以外だとlateinitな変数がInterceptingできない(?) ◦ https://github.com/kotlintest/kotlintest/issues/174 • BehaviorSpecがgiven-when-thenなので、予約語のwhenをエスケープ (`when`)しないといけない ◦ Spekはdescribe-on-it形式なのでエスケープ不要

  30. その他機能色々 • Property Testing • Table-driven Testing • Matchers •

    Inspectors • Eventually • etc...
  31. 参考 kotlintest/reference.md at master · kotlintest/kotlintest https://github.com/kotlintest/kotlintest/blob/master/doc/reference.md Spek User Guide

    http://spekframework.org/docs/latest/#_android
  32. おまけ 32 https://qiita.com/rkowase/items/54dc44537e9af519023e