Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Android Espresso UI Testing & UI/Application Exerciser Monkey

Android Espresso UI Testing & UI/Application Exerciser Monkey

An overview on how Espresso works for Android instrumentation testing, also there is an overview of Application Exerciser Monkey, a utility tool from the Android SDK.

Jorge E. Hernández

July 16, 2020
Tweet

More Decks by Jorge E. Hernández

Other Decks in Technology

Transcript

  1. Espresso - Testing framework for Android UI testing - Used

    by devs familiar with the Android app codebase - Lets you interact with your Android app just like any user would do - Runs on emulators or physical devices
  2. // Find the EditText onView(withId(R.id.editTextMessage)) // ... then type some

    text & close the soft keyboard .perform(typeText(TEXT_TO_BE_TYPED))
  3. // Find the EditText onView(withId(R.id.editTextMessage)) // ... then type some

    text & close the soft keyboard .perform(typeText(TEXT_TO_BE_TYPED), closeSoftKeyboard())
  4. // Find the EditText onView(withId(R.id.editTextMessage)) // ... then type some

    text & close the soft keyboard .perform(typeText(TEXT_TO_BE_TYPED), closeSoftKeyboard()) // Find the button
  5. // Find the EditText onView(withId(R.id.editTextMessage)) // ... then type some

    text & close the soft keyboard .perform(typeText(TEXT_TO_BE_TYPED), closeSoftKeyboard()) // Find the button onView(withId(R.id.buttonChangeText))
  6. // Find the EditText onView(withId(R.id.editTextMessage)) // ... then type some

    text & close the soft keyboard .perform(typeText(TEXT_TO_BE_TYPED), closeSoftKeyboard()) // Find the button, then click on it onView(withId(R.id.buttonChangeText))
  7. // Find the EditText onView(withId(R.id.editTextMessage)) // ... then type some

    text & close the soft keyboard .perform(typeText(TEXT_TO_BE_TYPED), closeSoftKeyboard()) // Find the button, then click on it onView(withId(R.id.buttonChangeText)) .perform(click())
  8. // Find the EditText onView(withId(R.id.editTextMessage)) // ... then type some

    text & close the soft keyboard .perform(typeText(TEXT_TO_BE_TYPED), closeSoftKeyboard()) // Find the button, then click on it onView(withId(R.id.buttonChangeText)) .perform(click()) // Find the TextView with the message
  9. // Find the EditText onView(withId(R.id.editTextMessage)) // ... then type some

    text & close the soft keyboard .perform(typeText(TEXT_TO_BE_TYPED), closeSoftKeyboard()) // Find the button, then click on it onView(withId(R.id.buttonChangeText)) .perform(click()) // Find the TextView with the message onView(withId(R.id.textViewMessage))
  10. // Find the EditText onView(withId(R.id.editTextMessage)) // ... then type some

    text & close the soft keyboard .perform(typeText(TEXT_TO_BE_TYPED), closeSoftKeyboard()) // Find the button, then click on it onView(withId(R.id.buttonChangeText)) .perform(click()) // Find the TextView with the message, then check text was changed onView(withId(R.id.textViewMessage))
  11. // Find the EditText onView(withId(R.id.editTextMessage)) // ... then type some

    text & close the soft keyboard .perform(typeText(TEXT_TO_BE_TYPED), closeSoftKeyboard()) // Find the button, then click on it onView(withId(R.id.buttonChangeText)) .perform(click()) // Find the TextView with the message, then check text was changed onView(withId(R.id.textViewMessage)) .check(matches(withText(TEXT_TO_BE_TYPED)))
  12. @RunWith(AndroidJUnit4::class) @LargeTest class ChangeTextBehaviorTest { @get:Rule var activityScenarioRule = activityScenarioRule<MainActivity>()

    @Test fun testTextIsChangedWhenButtonIsClicked() { // ... your test code here } } Where should we place this code?
  13. How to test a RecyclerView? // Find the RecyclerView onView(withId(R.id.myRecyclerView))

    // ... perform an action indicating the item position .perform( )
  14. How to test a RecyclerView? // Find the RecyclerView onView(withId(R.id.myRecyclerView))

    // ... perform an action indicating the item position .perform( RecyclerViewActions.actionOnItemAtPosition<>() )
  15. How to test a RecyclerView? // Find the RecyclerView onView(withId(R.id.myRecyclerView))

    // ... perform an action indicating the item position .perform( RecyclerViewActions.actionOnItemAtPosition<RecyclerView.ViewHolder>() )
  16. How to test a RecyclerView? // Find the RecyclerView onView(withId(R.id.myRecyclerView))

    // ... perform an action indicating the item position .perform( RecyclerViewActions.actionOnItemAtPosition<RecyclerView.ViewHolder>( 30, click() ) )
  17. How to test a RecyclerView? // Find the RecyclerView onView(withId(R.id.myRecyclerView))

    // ... perform an action indicating the item position .perform( RecyclerViewActions.actionOnItemAtPosition<RecyclerView.ViewHolder>( 30, // the position of the item in the RecyclerView click() ) )
  18. What if we don’t know the position? // Find the

    RecyclerView onView(withId(R.id.myRecyclerView)) // ... perform an action indicating the item position .perform( RecyclerViewActions.actionOnItem<RecyclerView.ViewHolder>( hasDescendant(withText(containsString("Your order total is"))), click() ) )
  19. What if we don’t know the position? // Find the

    RecyclerView onView(withId(R.id.myRecyclerView)) // ... perform an action indicating the item position .perform( RecyclerViewActions.actionOnItem<RecyclerView.ViewHolder>( hasDescendant(withText(containsString("Your order total is"))), click() ) )
  20. scrollTo() Scrolls to the matched View. scrollToHolder() Scrolls to the

    matched View Holder. scrollToPosition() Scrolls to a specific position. actionOnHolderItem() Performs a View Action on a matched View Holder. actionOnItem() Performs a View Action on a matched View. actionOnItemAtPosition() Performs a ViewAction on a view at a specific position. More RecyclerViewActions
  21. scrollTo() Scrolls to the matched View. scrollToHolder() Scrolls to the

    matched View Holder. scrollToPosition() Scrolls to a specific position. actionOnHolderItem() Performs a View Action on a matched View Holder. actionOnItem() Performs a View Action on a matched View. actionOnItemAtPosition() Performs a ViewAction on a view at a specific position. That’s it for Espresso… 🤓 More RecyclerViewActions
  22. UI/Application Exerciser Monkey • Program that runs on your emulator

    or device • Generates pseudo-random streams of events such as clicks, touches, or gestures, as well as a number of system-level events
  23. UI/Application Exerciser Monkey • Program that runs on your emulator

    or device • Generates pseudo-random streams of events such as clicks, touches, or gestures, as well as a number of system-level events • Use it to stress-test applications that you are developing, in a random yet repeatable manner
  24. UI/Application Exerciser Monkey Basic usage Example # Will send 500

    random events to the entire system adb shell monkey 500 adb shell monkey [options] <event-count>
  25. Stress testing your application # Will launch your application #

    Then, will send 500 random events adb shell monkey -p com.example.app
  26. Stress testing your application # Will launch your application #

    Then, will send 500 random events adb shell monkey -p com.example.app 500
  27. # Level 0 (the default) provides little information beyond startup

    notification, test completion, and final results. Verbosity levels
  28. # Level 0 (the default) provides little information beyond startup

    notification, test completion, and final results. # Level 1 provides more details about the test as it runs, such as individual events being sent to your activities. Verbosity levels
  29. # Level 0 (the default) provides little information beyond startup

    notification, test completion, and final results. # Level 1 provides more details about the test as it runs, such as individual events being sent to your activities. # Level 2 provides more detailed setup information such as activities selected or not selected for testing. Verbosity levels
  30. Verbosity levels # Level 0 (the default) provides little information

    beyond startup notification, test completion, and final results. # Level 1 provides more details about the test as it runs, such as individual events being sent to your activities. # Level 2 provides more detailed setup information such as activities selected or not selected for testing. adb shell monkey -p com.example.app -v -v -v 500
  31. Verbosity levels # Level 0 (the default) provides little information

    beyond startup notification, test completion, and final results. # Level 1 provides more details about the test as it runs, such as individual events being sent to your activities. # Level 2 provides more detailed setup information such as activities selected or not selected for testing. adb shell monkey -p com.example.app -v -v -v 500
  32. # Pass a seed value, then use it again #

    it will generate the same sequence of events. adb shell monkey -p com.example.app -s 7 500 How to reproduce?
  33. # Pass a seed value, then use it again #

    it will generate the same sequence of events. adb shell monkey -p com.example.app -s 7 500 How to reproduce?
  34. Throttling # Will send an event each second # Events

    include launching activities from ignored packages $ The --throttle argument is expressed in milliseconds adb shell monkey --throttle 1000 20
  35. Throttling # Will send an event each second # Events

    include launching activities from ignored packages $ The --throttle argument is expressed in milliseconds adb shell monkey --throttle 1000 20
  36. Touch events # Will send 20 events # All of

    them will be down-up events in a single place on the screen # Pretty much like a single tap on the screen adb shell monkey --pct-touch 100 20
  37. # Will send 20 events # All of them will

    be like swipes in a random manner adb shell monkey --pct-motion 100 20 Motion events
  38. # Will send 20 events, 10 touch events & 10

    motion events adb shell monkey --pct-touch 50 --pct-motion 50 20 Touch & Motion events combined
  39. # Trackball events adb shell monkey --pct-trackball 100 500 #

    Basic navigation events adb shell monkey --pct-nav 100 500 Additional monkey options
  40. # Trackball events adb shell monkey --pct-trackball 100 500 #

    Basic navigation events adb shell monkey --pct-nav 100 500 # "Major" navigation events like # center button in a 5-way pad, the back key, or the menu key adb shell monkey --pct-majornav 100 500 Additional monkey options
  41. # Trackball events adb shell monkey --pct-trackball 100 500 #

    Basic navigation events adb shell monkey --pct-nav 100 500 # "Major" navigation events like # center button in a 5-way pad, the back key, or the menu key adb shell monkey --pct-majornav 100 500 # System events # Home, Back, Start Call, End Call, Volume controls adb shell monkey --pct-syskeys 100 500 Additional monkey options
  42. # Trackball events adb shell monkey --pct-trackball 100 500 #

    Basic navigation events adb shell monkey --pct-nav 100 500 # "Major" navigation events like # center button in a 5-way pad, the back key, or the menu key adb shell monkey --pct-majornav 100 500 # System events # Home, Back, Start Call, End Call, Volume controls adb shell monkey --pct-syskeys 100 500 # Will launch your app via startActivity() adb shell monkey --pct-appswitch 100 500 Additional monkey options