KotlinでEspressoテストがもっと書きやすくなるKakaoを試してみた / Trying Kakao which makes Espresso test easier to write

KotlinでEspressoテストがもっと書きやすくなるKakaoを試してみた / Trying Kakao which makes Espresso test easier to write

2018/3/19開催のAndroid Test Night #3の発表資料です。

17997dee8a3da090f62d8cf8c494d8ff?s=128

TOYAMA Sumio

March 19, 2018
Tweet

Transcript

  1. Kotlin Espresso    Kakao  2018.03.19  

    (sumio)
  2. 04. p(': # 3 (TOYAMA Sumio) @sumio_tym (Twitter) / @sumio

    (GitHub) p$1: DeNA SWET  (Software Engineer in Test) p%):    p+/!: pDroidKaigi 2016-2018: Espresso UIAutomator p@IT2&,*  (UI Automator / Appium -") 2
  3. , Espresso: AndroidUI$"%#' Kotlin: Android+*0-1 75)2 4( KotlinEspresso$"%!& . 

    #' Kakao /  63 3
  4. Espresso pAndroid%+UI  Android Open Source Project, licensed under the

    Apache License, Version 2.0 https://d.android.com/training/testing/espresso/index.html 4  https://developer.android.com/training/testing/espresso/index.html &$ onView(ViewMatcher) .perform(ViewAction) .check(ViewAssertion); p ViewMatcher View" p ViewAction#! ') p ViewViewAssertion,  *( 
  5. Kakao pAgoda  2017, licensed under the Apache License, Version

    2.0 GitHub(): https://github.com/agoda-com/Kakao API doc: https://goo.gl/ThVN6J pGitHub ! : Nice and simple DSL for Espresso in Kotlin p     Iñaki VillarOne Espresso with Kotlin, please in GDG DevFest Bangkok 2017 https://speakerdeck.com/cdsap/one-espresso-with-kotlin-please 5  https://github.com/agoda-com/Kakao/blob/1.2.1/README.md 
  6.  6 repositories { jcenter() } dependencies { androidTestImplementation 'com.agoda.kakao:kakao:1.2.1'

    } ! Espresso3.0.1 )' RecyclerView GitHubmaster#(" % (1.2.1  &$)
  7.  7 @Rule @JvmField val rule = ActivityTestRule(MyActivity::class.java) val screen

    = MyActivityScreen() @Test fun myKakaoTest() { screen { myButton { click() } myTextView { hasText("Clicked!") } } }
  8.    8 @Rule @JvmField val rule = ActivityTestRule(MyActivity::class.java)

    val screen = MyActivityScreen() @Test fun myKakaoTest() { screen { myButton { click() } myTextView { hasText("Clicked!") } } } screen Screen(UI) 
  9.  9 @Rule @JvmField val rule = ActivityTestRule(MyActivity::class.java) val screen

    = MyActivityScreen() @Test fun myKakaoTest() { screen { myButton { click() } myTextView { hasText("Clicked!") } } } perform(ViewAction) check(ViewAssertion)  Kakao
  10. Screen 10 open class MyActivityScreen: Screen<MyActivityScreen>() { val myButton: KButton

    = KButton { withId(R.id.button) withText("OK") } val myTextView: KTextView = KTextView { withId(R.id.textView) } }
  11. Screen 11 open class MyActivityScreen: Screen<MyActivityScreen>() { val myButton: KButton

    = KButton { withId(R.id.button) withText("OK") } val myTextView: KTextView = KTextView { withId(R.id.textView) } } Screen
  12. Screen  12 open class MyActivityScreen: Screen<MyActivityScreen>() { val myButton:

    KButton = KButton { withId(R.id.button) withText("OK") } val myTextView: KTextView = KTextView { withId(R.id.textView) } } ViewKakao KBaseView  https://goo.gl/qveQ48
  13. Screen  13 open class MyActivityScreen: Screen<MyActivityScreen>() { val myButton:

    KButton = KButton { withId(R.id.button) withText("OK") } val myTextView: KTextView = KTextView { withId(R.id.textView) } } onView(ViewViewMatcher)     AND
  14. RecyclerView Espresso: RecyclerViewActions p : (  ) Kakao: KRecycler{View,Item}

    p    (KRecyclerItem) 14
  15. KRecyclerItem) 15 Title 0 OK Title 4 OK Title 3

    OK Title 2 OK Title 1 OK Title 0 OK R.id.title R.id.button ( Title 0 Clicked
  16.  KRecyclerItem) 16 open class MyRecyclerScreen : Screen<MyRecyclerScreen>() { ...

    class Item(parent: Matcher<View>) : KRecyclerItem<Item>(parent) { val title: KTextView = KTextView(parent) {withId(R.id.title)} val button: KButton = KButton(parent) {withId(R.id.button)} } }
  17. ( KRecyclerItem) 17 open class MyRecyclerScreen : Screen<MyRecyclerScreen>() { ...

    class Item(parent: Matcher<View>) : KRecyclerItem<Item>(parent) { val title: KTextView = KTextView(parent) {withId(R.id.title)} val button: KButton = KButton(parent) {withId(R.id.button)} } } KRecyclerItem (
  18. KRecyclerItem) 18 open class MyRecyclerScreen : Screen<MyRecyclerScreen>() { ... class

    Item(parent: Matcher<View>) : KRecyclerItem<Item>(parent) { val title: KTextView = KTextView(parent) {withId(R.id.title)} val button: KButton = KButton(parent) {withId(R.id.button)} } } (
  19. RecyclerViewScreen 19 open class MyRecyclerScreen : Screen<MyRecyclerScreen>() { val recycler:

    KRecyclerView = KRecyclerView({ withId(R.id.recycler_view) }, itemTypeBuilder = { itemType(::Item) } ); class Item(parent: Matcher<View>) : KRecyclerItem<Item>(parent) { ... } }
  20. RecyclerViewScreen 20 open class MyRecyclerScreen : Screen<MyRecyclerScreen>() { val recycler:

    KRecyclerView = KRecyclerView({ withId(R.id.recycler_view) }, itemTypeBuilder = { itemType(::Item) } ); class Item(parent: Matcher<View>) : KRecyclerItem<Item>(parent) { ... } }    
  21. RecyclerView 21 val screen = MyRecyclerScreen() @Test fun testRecyclerView() {

    screen { recycler { childAt<MyRecyclerScreen.Item>(0) { title { hasText("Title 0") } button { click() hasText("Clicked") } }}}}
  22. RecyclerView 0 22 val screen = MyRecyclerScreen() @Test fun testRecyclerView()

    { screen { recycler { childAt<MyRecyclerScreen.Item>(0) { title { hasText("Title 0") } button { click() hasText("Clicked") } }}}}
  23. RecyclerView 0 23 val screen = MyRecyclerScreen() @Test fun testRecyclerView()

    { screen { recycler { childAt<MyRecyclerScreen.Item>(0) { title { hasText("Title 0") } button { click() hasText("Clicked") } }}}}  
  24. RecyclerView  24 val screen = MyRecyclerScreen() @Test fun testRecyclerView()

    { screen { recycler { childAt<MyRecyclerScreen.Item>(0) { title { hasText("Title 0") } button { click() hasText("Clicked") } }}}}  KRecyclerItem     
  25. RecyclerView 25 val screen = MyRecyclerScreen() @Test fun testRecyclerView() {

    screen { recycler { childWith<MyRecyclerScreen.Item> { withDescendant { withText("Title 0") } } perform { title { ... } button { ... }}}}}
  26. RecyclerView   26 val screen = MyRecyclerScreen() @Test fun

    testRecyclerView() { screen { recycler { childWith<MyRecyclerScreen.Item> { withDescendant { withText("Title 0") } } perform { title { ... } button { ... }}}}}    
  27. RecyclerView   27 val screen = MyRecyclerScreen() @Test fun

    testRecyclerView() { screen { recycler { childWith<MyRecyclerScreen.Item> { withDescendant { withText("Title 0") } } perform { title { ... } button { ... }}}}} childWith()  perform
  28.  :   p  Espresso  pespresso-intent: KIntent

    p: https://goo.gl/ZiHuY3 pespresso-web: KWebView p: https://goo.gl/mfNYMa 28
  29. 0)* pEspresso API 4 +%  !1 3.( p KBaseView

    : https://goo.gl/qveQ48 p ViewBuilder : https://goo.gl/esEMsf p BaseAction  : https://goo.gl/wNB82F p BaseAssertions   : https://goo.gl/3rYFMQ pEspresso 'API#/ $& p -) Espresso API2 "API, (matches / assert / act) 29
  30.   pEspresso KotlinDSL 7 KakaoG? p$!#DSL (  pRecyclerView@B/+<

    pAPI9ED%; (API docC3  ) p42 .= 1-2*F 6 A0) ,> p2018&3'5:8*"   30
  31.     31