Android UI Unit Testing with Espresso

Version 6.1 by Divyansh Jain on 2019/06/26

Jun 26 2019

Warning
This blog post is not published yet.

Android UI Unit Testing with Espresso


Unit testing is a way to test individual units/components of the app. It helps to break down the app into individual units/components so that we can focus on that individual unit only. As test runs, we compare the test results with expected behavior which helps us to identify even a single flaw too. For this post, I choose the UI testing.

UI Testing: The basic concept of the UI testing is the same as Unit Testing, but here we run UI components like login, signup, etc. on Emulator or test device. This allows us to replicate the user UI interaction while testing. So when we run, say login test on emulator, we replicate the user entering its credentials and see whether his credentials are correct or not. Here, two major things are used:

  1. Espresso: Here interaction is done by Espresso. Espresso helps us to simulate the user interaction with UI. It can typeText, clear text, click on the button, scroll to a list, swipe left, swipe right, etc. In summary, it can perform all user interactions that user do on the UI which is very simple to use. For example:
    1. Let’s say that you want to enter username in the edittext on the screen, then execute:

      onView(withId(R.id.accountName).perform(typeText("TestUser")) 

      Here onView(withId(R.id.accountName) is compulsory as it checks for the view (R.id.accountName) on the current view also known as the 'viewMatcher'. So if the view exists, then it performs the 'viewAction'. Here viewAction-  "perform(typeText("TestUser"))" writes the text “TestUser” in the field.
    2. You can also put check() which verifies the content of the given view. Say you want to check the text written on the button or check if textView content has changed or not, in that case, we run:

      onView(withId(R.id.tvExample)).check(matches(withText("Hello")))

      Here onView function is same as in the above example. And next check method is a viewInteraction which matches the current view i.e tvExample with the text “Hello”. So if the text is matched, then test will pass, otherwise it will not.
    3. It can also check for the data loading into the Adapter. Espresso provides onData() method. By using onData(), we force our desired element into the view hierarchy. Say in your adapter, there’s an item “Coffee” of string type.

      onData(allOf(`is`(instanceOf(String::class.java))
      ,`is`("Coffee"))).perform(click())


      Earlier we were using onView() to find the view, but it cannot find the view that has not been loaded yet, so here we use onData() to match the string “Coffee” into the list.
  2. Idling Resource: As the Android Developers Documentation states: “An idling resource represents an asynchronous operation whose results affect subsequent operations in a UI test.”  By using Idling Resource, we can notify Espresso to wait for the completion of Asynchronous operation and then execute the rest of the code. Let’s assume that there are cases where you are loading the data in the RecyclerView/ListView. What happens now? Yes, it will not wait for the completion of the Asynchronous operation; it will end the test case immediately. You may find some simple solutions like putting SystemClock.sleep(period) or Thread.sleep(period) but these are not good practices as you cannot determine the amount of time it will take for your Asynchronous operation to complete. Load the data and display it.

    That’s where Idling resource comes to rescue. It notifies the Espresso that an Asynchronous operation is made and that you have to wait for it. Then as soon as the operation is completed, it loads the data and displays it.

Get Connected