Open In App

UI Testing with Espresso in Android Studio

Last Updated : 11 Jul, 2021
Improve
Improve
Like Article
Like
Save
Share
Report

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 

  1. The basics of the Espresso framework, 
  2. How to set up the Espresso framework in Android, and 
  3. How to automate the testing environment with a simple android application.

1. Basics of the Espresso framework

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

2. Setting up the espresso framework in Android

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

3. Automating the testing environment with a simple android application

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: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



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads