Save 37% off PRO during our Black Friday Sale! »

Espresso Idling Resource

Espresso Idling Resource

E28404a128b6014e6f499d2a967c72a0?s=128

Takuji Nishibayashi

August 29, 2017
Tweet

Transcript

  1. Espresso Idling Resource ☕ @takuji31

  2. @takuji31 (Takuji Nishibayashi) Applica7on Engineer at Hatena

  3. Loves • ! (AVG 175) • " # • h,p:/

    /photo.takuji31.jp • $ • h,p:/ /nazuna.takuji31.jp • Android • Kotlin
  4. AGENDA • UIςετΛॻ࣌͘ͷ೰Έ • ղܾํ๏ • Espresso Idling Resource •

    ϋϚΓͲ͜Ζ
  5. UIςετΛॻ࣌͘ͷ೰Έ

  6. ඇಉظͷςετ

  7. ςετ͕ՄೳʹͳΔ·Ͱ଴ͭ

  8. ࡶͳղܾํ๏

  9. Thread.sleep(1000)

  10. ωοτϫʔΫ͕஗͍

  11. ͨ·ʹίέΔ !

  12. Jenkins͕ॏ͍

  13. ͨ·ʹίέΔ !

  14. ͪΐͬͱݡ͍ํ๏

  15. खͰؤுΔ

  16. RxJava

  17. Թ͔Έͷ͋Δख࣮૷

  18. ෳ਺ίϯϙʔωϯτΛ଴ͭͷ͕େม Ac#vity + ViewModelͱ͔

  19. ຊ࣭తͰͳ͍ͱ͜Ζʹίετ͕͔͔ Γ͗͢Δ

  20. ઈର΍Γͨ͘ͳ͍ !

  21. Espresso Idling Resource

  22. Espresso plugin?

  23. ΞΠυϦϯάͷ࢓૊ΈΛఏڙ

  24. IdlingResource

  25. Ϧιʔε

  26. IdlingRegistry

  27. ΞΠυϦϯάΛ؂ࢹ͢ΔϨδετϦ ʔ

  28. ࢖͍ํ

  29. build.gradle compile 'com.android.support.test.espresso:espresso-idling-resource:3.0.0'

  30. IdlingResource

  31. SimpleIdlingResource class SimpleIdlingResource(private val name: String) : IdlingResource { private

    var callback: IdlingResource.ResourceCallback? = null var isIdle: Boolean = false set(value) { field = value if (value) { callback?.run { onTransitionToIdle() } } } override fun getName(): String = this.name override fun isIdleNow(): Boolean = isIdle override fun registerIdleTransitionCallback(callback: IdlingResource.ResourceCallback?) { this.callback = callback } }
  32. ࢖͏

  33. ΞϓϦ

  34. ViewModel class ViewModel { var artists: List<Artist> = emptyList() var

    loadingDisposable: Disposable? = null @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) val loadingIdlingResource : SimpleIdlingResource = SimpleIdlingResource("IdlingResourceViewModelLoading") }
  35. ViewModel class ViewModel { fun onCreate() { // fake API

    request fakeReload() } private fun fakeReload() { loadingDisposable = Single .timer(3, TimeUnit.SECONDS) .doOnSubscribe { loadingIdlingResource.isIdle = false } .doFinally { loadingIdlingResource.isIdle = true } .subscribe { _, _ -> artists = Artist.list } } }
  36. ςετ

  37. test class IdlingResourceActivityTest { @JvmField @Rule val rule : IntentsTestRule<IdlingResourceActivity>

    = IntentsTestRule(IdlingResourceActivity::class.java, true, true) var initializeIdlingResource : IdlingResource? = null }
  38. test class IdlingResourceActivityTest { @Before fun setUp() { initializeIdlingResource =

    rule.activity.viewModel.loadingIdlingResource IdlingRegistry.getInstance().register(initializeIdlingResource) } @After fun tearDown() { initializeIdlingResource?.run { IdlingRegistry.getInstance().unregister(this) initializeIdlingResource = null } } }
  39. test class IdlingResourceActivityTest { @Test fun testReload() { // remove

    3 items repeat(3) { openActionBarOverflowOrOptionsMenu(rule.activity) onView(withText("Remove first")).perform(click()) } onView(withId(R.id.swipeRefreshLayout)).perform(swipeDown()) onView(withId(R.id.recyclerView)).check { view, _ -> val recyclerView = view as RecyclerView assertEquals(recyclerView.childCount, Artist.list.size) assertEquals(recyclerView.adapter.itemCount, Artist.list.size) } } }
  40. EspressoͷػೳΛ࢖Θͳ͍͚Ͳ଴ͪ ͍ͨ

  41. ex) GA΁ͷΠϕϯτૹ৴Λςετ

  42. Espresso.onIdle()

  43. ༻ҙ͞Ε͍ͯΔIdlingResource

  44. CountingIdlingResource

  45. ηϚϑΥͬΆ͍΍ͭ

  46. increment()/decrement()

  47. IdlingScheduledThreadPoolExecutor / IdlingThreadPoolExecutor

  48. ThreadPoolExecutor

  49. UriIdlingResource

  50. UriΛΩʔʹͰ͖ΔIdlingResource

  51. ϋϚΓͲ͜Ζ

  52. Test with Proguard

  53. None
  54. !

  55. Proguard rule -keep class android.support.test.espresso.** { public *; }

  56. takuji31/KanmobaAndroid

  57. Enjoy Espresso life !