UI Testing with Espresso in Android Studio

11 Jul, 2021
UI testing is the process of testing the visual elements of an application to ensure whether they appropriately meet the anticipated functionality. Verifying the application manually whether it works or not is a time taking and tiring process, but using espresso we can write automated tests that run fast and scale well. Espresso is an automated user interface testing framework for Android, developed by Google in 2013. In this article, we will be discussing 
The basics of the Espresso framework, How to set up the Espresso framework in Android, and How to automate the testing environment with a simple android application.
The basics of the Espresso framework, 
How to set up the Espresso framework in Android, and 
How to automate the testing environment with a simple android application.
Anatomy of a UI Test
Find a View
Perform an action
Inspect the result
Espresso consists of mainly three components:
ViewMatchers – It is used for finding a view using different attributes like withId(), withText(), withTagKey(), etc.
ViewActions – It is used for performing the actions on the view defined in ViewMatchers like click(), longClick(), scrollTo(), etc.
ViewAssertions – It is used to assert that the view found using ViewMatchers and expected views are the same using match(), doesNotExist(), etc.
Since espresso takes care of synchronization with any UI events, we don’t have to worry about any view state transitions and implementation details. Now let’s have a look at the boilerplate code for running an automated test. 
onView(ViewMatcher)       // onView takes a viewMatcher like R.id.button
 .perform(ViewAction)     // perform takes a viewAction like pressing the button 
   .check(ViewAssertion); // check inspects if the output result is same as the expected result. 
In this article, we will be using only certain types of ViewMatchers, ViewActions, and ViewAssertions, however, there are many more of them which can be found on the official website https://developer.android.com/training/testing/espresso/cheat-sheet
Step 1: Add the espresso library in dependencies
Navigate to app > Gradle Script > build.gradle (Module:app), add the following lines of code, and sync the project. 
defaultConfig {
    testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
dependencies {
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
    androidTestImplementation 'androidx.test:runner:1.3.0'
    androidTestImplementation 'androidx.test:rules:1.3.0'
}
Step 2: Turn off animations from the Android device
Navigate to Settings > Developer options and turn off the following options: 
Window animation scale
Transition animation scale
Animator duration scale
We will be building an application where a user can choose his preferred language, and the chosen language is displayed in the textView. Now, we will be implementing an automated test to validate if the chosen preferred language of the user is displayed in the TextView or not.  A sample GIF is given below to get an idea about what we are going to do in this part.
Step 1: Create a New Project
To create a new project in Android Studio please refer to https://www.geeksforgeeks.org/android-how-to-create-start-a-new-project-in-android-studio/. Note that select Java as the programming language.
Step 2: Set up the espresso framework in Android as discussed in part 2 above.
Step 3: Working with the activity_main.xml file
Navigate to the app > res > layout > activity_main.xml and add the below code to that file. Below is the code for the activity_main.xml file. 
XML
<?xml version="1.0" encoding="utf-8"?><RelativeLayout     xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context=".MainActivity">      <TextView        android:id="@+id/select_language"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_centerHorizontal="true"        android:layout_marginTop="28dp"        android:text="Select Your Preferred Language"        android:textSize="19sp"        android:textStyle="bold" />      <!-- LinearLayout contains all the          languages button in a vertical order-->    <LinearLayout        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_below="@+id/select_language"        android:id="@+id/linear_layout"        android:layout_centerHorizontal="true"        android:layout_margin="22dp"        android:orientation="vertical">          <Button            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:padding="16dp"            android:id="@+id/english"            android:text="English"            android:onClick="onClick"            android:textAllCaps="true"            android:textColor="#0F9D58"            android:textStyle="bold" />          <Button            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:padding="16dp"            android:id="@+id/german"            android:onClick="onClick"            android:text="German"            android:textAllCaps="true"            android:textColor="#0F9D58"            android:textStyle="bold" />          <Button            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:id="@+id/french"            android:padding="16dp"            android:onClick="onClick"            android:text="French"            android:textAllCaps="true"            android:textColor="#0F9D58"            android:textStyle="bold" />          <Button            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:textColor="#0F9D58"            android:id="@+id/hindi"            android:onClick="onClick"            android:text="Hindi"            android:padding="16dp"            android:textAllCaps="true"            android:textStyle="bold"/>          <Button            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:textColor="#0F9D58"            android:id="@+id/urdu"            android:onClick="onClick"            android:text="Urdu"            android:padding="16dp"            android:textAllCaps="true"            android:textStyle="bold"/>    </LinearLayout>      <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:id="@+id/chosen"        android:layout_centerHorizontal="true"        android:layout_marginTop="28dp"        android:text="Your Chosen Language is : "        android:textSize="19sp"        android:textStyle="bold"        android:layout_below="@+id/linear_layout"/>      <!-- The following textView shows the          preferred language chosen by the user. -->    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:id="@+id/preferred_language"        android:layout_centerHorizontal="true"        android:layout_marginTop="28dp"        android:hint="-------------"        android:textSize="19sp"        android:textStyle="bold"        android:layout_below="@+id/chosen"/>  </RelativeLayout>
Step 4: Working with the MainActivity.java file
Go to the MainActivity.java file and refer to the following code. Below is the code for the MainActivity.java file. 
Java
import androidx.appcompat.app.AppCompatActivity;  import android.os.Bundle;import android.view.View;import android.widget.TextView;  public class MainActivity extends AppCompatActivity {        // Textview to show the language      // chosen by the user    TextView preferred_language;        // onClick is called whenever       // a user clicks a button     public void onClick(View view) {          // whenever a user chooses a preferred language          // by tapping button, it changes the chosen           // language textView         switch (view.getId()){            case R.id.english:                preferred_language.setText("English");                break;            case R.id.french:                preferred_language.setText("French");                break;            case R.id.german:                preferred_language.setText("German");                break;            case R.id.hindi:                preferred_language.setText("Hindi");                break;            case R.id.urdu:                preferred_language.setText("Urdu");                break;        }    }      @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);                    // initializing the textview        preferred_language = findViewById(R.id.preferred_language);      }}
Step 5: Navigate to app > java > package-name(androidTest) > ExampleInstrumentedTest. Open the ExampleInstrumentedTest.java file and refer to the following code. Below is the code for the ExampleInstrumentedTest.java file. Comments are added to describe ViewMatchers, ViewActions, and ViewAssertions in the following code snippet. 
Java
import androidx.test.ext.junit.rules.ActivityScenarioRule;import androidx.test.ext.junit.runners.AndroidJUnit4;  import org.junit.Rule;import org.junit.Test;import org.junit.runner.RunWith;  import static androidx.test.espresso.Espresso.onView;import static androidx.test.espresso.action.ViewActions.click;import static androidx.test.espresso.assertion.ViewAssertions.matches;import static androidx.test.espresso.matcher.ViewMatchers.withId;import static androidx.test.espresso.matcher.ViewMatchers.withText;  @RunWith(AndroidJUnit4.class)  public class ExampleInstrumentedTest{      // rule specifies that we are       // running test on MainActivity    @Rule     public ActivityScenarioRule<MainActivity> activityScenarioRule = new ActivityScenarioRule<>(MainActivity.class);       // test to check if the preferred language       // of user is displayed under the chosen language or not    @Test    public void selectLanguageAndCheck(){        onView(withId(R.id.german)) // ViewMatchers - withId(R.id.german) is to                                       // specify that we are looking for Button                                      // with id = R.id.german                .perform(click()); // ViewActions - Performs click action on view.        onView(withId(R.id.preferred_language)) // ViewMatchers - withId(R.id.preferred_language)                                                  // is to specify that we are looking for a TextView                                                  // with id = R.id.preferred_language                .check(matches(withText("German"))); // ViewAssertions - validates if preferred_language                                                       // matches with the text "German" since we                                                        // pressed german language button.      }}
Step 6 : Navigate to app > java > package-name(androidTest) > ExampleInstrumentedTest > Right Click and choose Run ExampleInstrumentedTest. This will run an automated test on an emulator/physical device and the result will be shown in the console once the test reaches completion. 
Output: The test case is passed and it took only 666ms to run an automated test. This shows the espresso library can be quite handy when we need to test the UI elements in an application even on a very large scale. A slow-motion video of the test case is attached below since automated tests are quite fast.
GitHub Repository: https://github.com/garg-lucifer/GFGespresso
Android-Studio
Picked
Android
Android
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
How to Add Views Dynamically and Store Data in Arraylist in Android?
Android SDK and it's Components
Flutter - Custom Bottom Navigation Bar
How to Communicate Between Fragments in Android?
Retrofit with Kotlin Coroutine in Android
How to Post Data to API using Retrofit in Android?
Flutter - Stack Widget
Introduction to Android Development
Activity Lifecycle in Android with Demo App
Fragment Lifecycle in Android