Lock in $30 Savings on PRO—Offer Ends Soon! ⏳

Getting Started with AndroidX Test

Getting Started with AndroidX Test

Testing on Android is slowly becoming more approachable. With AndroidX Test, you can use a single test API to run your instrumentation tests either on your mobile device, or on your computer using Robolectric. This is great, so how do you start? In this talk you’ll learn how to use AndroidX Test and Espresso to get started writing Integration tests for your app.

Victoria Gonda

April 23, 2019
Tweet

More Decks by Victoria Gonda

Other Decks in Programming

Transcript

  1. @TTGonda victoriagonda.com Why Test? • Make changes with confidence •

    Living documentation • Encourages maintainable, clean code
  2. @TTGonda victoriagonda.com Victoria Gonda • Android Engineer at Buffer •

    Author and Editor at RayWenderlich.com • Chicago native • Hedgehog and cat owner • she/her
  3. @TTGonda victoriagonda.com Testing Tools • JUnit4 • JUnit5 • Retrofit-mock

    • Espresso • Mockito • Robolectric • Spek • KotlinTest • MockK • Kakao • Hiroaki • Barista • Biscotti • AndroidX Test
  4. @TTGonda victoriagonda.com AndroidX Test • Includes some of the libraries

    you already know, plus some new ones • Aims to solve the issue of too many libraries • Can be run both on device or on the JVM
  5. @TTGonda victoriagonda.com @Test fun mainActivityShowsAddButton() { val scenario = ActivityScenario

    .launch(MainActivity::class.java) onView(withId(R.id.buttonAddList)) .check(matches(isDisplayed())) }
  6. @TTGonda victoriagonda.com @Test fun mainActivityShowsAddButton() { val scenario = ActivityScenario

    .launch(MainActivity::class.java) onView(withId(R.id.buttonAddList)) .check(matches(isDisplayed())) }
  7. @TTGonda victoriagonda.com @Test fun selectingListOpensDetailActivity() { ActivityScenario.launch(MainActivity::class.java) Intents.init() onView(withId(R.id.recyclerView)) .perform(RecyclerViewActions

    .actionOnItemAtPosition<TaskListViewHolder>(0, click())) Intents.intended(IntentMatchers .hasComponent(DetailActivity::class.java.name)) Intents.release() }
  8. @TTGonda victoriagonda.com @Test fun selectingListOpensDetailActivity() { ActivityScenario.launch(MainActivity::class.java) Intents.init() onView(withId(R.id.recyclerView)) .perform(RecyclerViewActions

    .actionOnItemAtPosition<TaskListViewHolder>(0, click())) Intents.intended(IntentMatchers .hasComponent(DetailActivity::class.java.name)) Intents.release() }
  9. @TTGonda victoriagonda.com @Test fun selectingListOpensDetailActivity() { ActivityScenario.launch(MainActivity::class.java) Intents.init() onView(withId(R.id.recyclerView)) .perform(RecyclerViewActions

    .actionOnItemAtPosition<TaskListViewHolder>(0, click())) Intents.intended(IntentMatchers .hasComponent(DetailActivity::class.java.name)) Intents.release() }
  10. @TTGonda victoriagonda.com @Test fun selectingListOpensDetailActivity() { ActivityScenario.launch(MainActivity::class.java) Intents.init() onView(withId(R.id.recyclerView)) .perform(RecyclerViewActions

    .actionOnItemAtPosition<TaskListViewHolder>(0, click())) Intents.intended(IntentMatchers .hasComponent(DetailActivity::class.java.name)) Intents.release() }
  11. @TTGonda victoriagonda.com @Test fun selectingListOpensDetailActivity() { ActivityScenario.launch(MainActivity::class.java) Intents.init() onView(withId(R.id.recyclerView)) .perform(RecyclerViewActions

    .actionOnItemAtPosition<TaskListViewHolder>(0, click())) Intents.intended(IntentMatchers .hasComponent(DetailActivity::class.java.name)) Intents.release() }
  12. @TTGonda victoriagonda.com @Test fun selectingListOpensDetailActivity() { ActivityScenario.launch(MainActivity::class.java) Intents.init() onView(withId(R.id.recyclerView)) .perform(RecyclerViewActions

    .actionOnItemAtPosition<TaskListViewHolder>(0, click())) Intents.intended(IntentMatchers .hasComponent(DetailActivity::class.java.name)) Intents.release() }
  13. @TTGonda victoriagonda.com @Test fun selectingListOpensDetailActivity() { ActivityScenario.launch(MainActivity::class.java) Intents.init() onView(withId(R.id.recyclerView)) .perform(RecyclerViewActions

    .actionOnItemAtPosition<TaskListViewHolder>(0, click())) Intents.intended(IntentMatchers .hasComponent(DetailActivity::class.java.name)) Intents.release() }
  14. @TTGonda victoriagonda.com @Test fun selectingListOpensDetailActivity() { ActivityScenario.launch(MainActivity::class.java) Intents.init() onView(withId(R.id.recyclerView)) .perform(RecyclerViewActions

    .actionOnItemAtPosition(0, click())) val intent = getIntents().first() IntentSubject.assertThat(intent) .hasComponentClass(DetailActivity::class.java) Intents.release() }
  15. @TTGonda victoriagonda.com @Test fun selectingListOpensDetailActivity() { ActivityScenario.launch(MainActivity::class.java) Intents.init() onView(withId(R.id.recyclerView)) .perform(RecyclerViewActions

    .actionOnItemAtPosition(0, click())) val intent = getIntents().first() IntentSubject.assertThat(intent) .hasComponentClass(DetailActivity::class.java) Intents.release() }
  16. @TTGonda victoriagonda.com val intent = DetailActivity.newIntent(tasklist, ApplicationProvider.getApplicationContext()) val bundleSubject: BundleSubject

    = assertThat(intent).extras() bundleSubject.containsKey("EXTRA_TASKLIST") val integerSubject: IntegerSubject = bundleSubject.integer("EXTRA_TASKLIST") integerSubject.isEqualTo(tasklist.id)
  17. @TTGonda victoriagonda.com fun newIntent(list: Tasklist, context: Context): Intent { return

    Intent(context, DetailActivity::class.java) .apply { putExtra("EXTRA_TASKLIST", list.id) } }
  18. @TTGonda victoriagonda.com val intent = DetailActivity.newIntent(tasklist, ApplicationProvider.getApplicationContext()) val bundleSubject: BundleSubject

    = assertThat(intent).extras() bundleSubject.containsKey("EXTRA_TASKLIST") val integerSubject: IntegerSubject = bundleSubject.integer("EXTRA_TASKLIST") integerSubject.isEqualTo(tasklist.id)
  19. @TTGonda victoriagonda.com val intent = DetailActivity.newIntent(tasklist, ApplicationProvider.getApplicationContext()) val bundleSubject: BundleSubject

    = assertThat(intent).extras() bundleSubject.containsKey("EXTRA_TASKLIST") val integerSubject: IntegerSubject = bundleSubject.integer("EXTRA_TASKLIST") integerSubject.isEqualTo(tasklist.id)
  20. @TTGonda victoriagonda.com val intent = DetailActivity.newIntent(tasklist, ApplicationProvider.getApplicationContext()) val bundleSubject: BundleSubject

    = assertThat(intent).extras() bundleSubject.containsKey("EXTRA_TASKLIST") val integerSubject: IntegerSubject = bundleSubject.integer("EXTRA_TASKLIST") integerSubject.isEqualTo(tasklist.id)
  21. @TTGonda victoriagonda.com Wanted to match 1 intents. Actually matched 0

    intents. IntentMatcher: has component: has component with: class name: is "com.victoriagonda.android.tasklist.DetailActivity" package name: an instance of java.lang.String short class name: an instance of java.lang.String Matched intents:[] Recorded intents: -Intent { cmp=com.victoriagonda.android.tasklist/.MainActivity (has extras) } handling packages:[[com.victoriagonda.android.tasklist]], extras:[Bundle[{EXTRA_TASKLIST=1}]])
  22. @TTGonda victoriagonda.com value of : intent.getExtras() expected to contain key

    EXTRA_TASKLIST but was : Bundle[{EXTRA_TASKNAME=Laundry}]
  23. @TTGonda victoriagonda.com • MotionEvent • PointerCoords • PointerProperties • IntentCorrespondences

    • IntentCorrespondences • NotificationAction • Notification • PendingIntent
  24. @TTGonda victoriagonda.com Wrapping Up • Google wrapped up all testing

    under one AndroidX roof • Four parts, JUnit, Core, Espresso, Truth • Can ALL be run on or off device • Hopefully means less APIs to learn and less worry about on or off device