Testing in Android : Part 5 : Automated UI Test using Espresso

ANDROID UI TESTING USING ESPRESSO:


UI testing can be done by a human tester performing a set of user operations on the Application and verify that it is behaving as expected. Main problem with this approach is that it is time consuming, tedious and error-prone. Instead, we can use automated approach to simulate user actions on the application easily in a repeatable manner.

  • test code is written inside (src/androidTest/java) folder. ( same folder we have used for Instrumented Unit Tests here ).
  • Create one new class AutomatedUiTest.java inside this folder..
  • For testing android applications, we can have two different types of automated UI tests :
    • Test for single app : This type of test is performed to check only the test application .
    • Test for multiple apps : This type of test is performed to test the behaviour of interactions between test application and other user applications and/or between system applications. e.g. we are developing a camera application and we want to check if it can share photo to other photo viewer application or not.
Android Testing Support Library includes a testing framework called Espresso that we can use to write UI tests for devices with Android 2.2 and higher. Espresso works with AndroidJUnitRunner test runner .

SETUP :

include the following dependency to your build.gradle file :
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.1'
Espresso has 3 components :
  1.  Find view we want to test in an Activity : By calling onView() method or if you are using AdapterView , use onData() method.
  2. Perform Action : ViewInteraction and DataInteraction object is returned for onView() and onData() method. we can call perform() method on these objects to pass a user action .
  3. Verify result : Use ViewInteraction.check() method to check a view state.

e.g :

onView(withId(R.id.id_view)).perform(click()).check(matches(isDisplayed()));

Example :
 
In this tutorial, we will create one simple login page, input username and password and finally click on the “login” button. One text view will be used to display success or failure.
  1. Update your activity_main.xml file as below :

    <?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"
    android:background="#303F9F"
    android:focusable="true"
    android:focusableInTouchMode="true"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin">
    <android.support.design.widget.TextInputLayout
    android:id="@+id/layout_email"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textColorHint="#B2EBF2">
    
    <EditText
    android:id="@+id/editTextEmail"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="email"
    android:inputType="textEmailAddress"
    android:textColor="#E0F7FA" />
    </android.support.design.widget.TextInputLayout>
    
    <android.support.design.widget.TextInputLayout
    android:id="@+id/layout_password"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@id/layout_email"
    android:textColorHint="#B2EBF2"
    >
    
    <EditText
    android:id="@+id/editTextPassword"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="45dp"
    android:hint="password"
    android:inputType="textPassword"
    android:textColor="#E0F7FA" />
    </android.support.design.widget.TextInputLayout>
    
    <Button
    android:id="@+id/button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentEnd="true"
    android:layout_alignParentLeft="true"
    android:layout_alignParentRight="true"
    android:layout_alignParentStart="true"
    android:layout_below="@+id/layout_email"
    android:layout_marginTop="104dp"
    android:background="#00BCD4"
    android:text="Login"
    android:textColor="#E0F7FA" />
    
    <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:inputType="text"
    android:layout_below="@+id/button"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="50dp"
    android:textColor="#E0F7FA"
    android:id="@+id/textViewResult" />
    </RelativeLayout>
  1. Add the following to your MainActivity.java

    mLoginButton = (Button) findViewById(R.id.button);
    mEmailET = (EditText) findViewById(R.id.editTextEmail);
    mPasswordET = (EditText) findViewById(R.id.editTextPassword);
    mResultTV = (TextView) findViewById(R.id.textViewResult);
    mLoginButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
    if (mEmailET.getText().toString().equals("codevscolor@gmail.com") && mPasswordET.getText().toString().equals("password"))
    mResultTV.setText("success");
    else
    mResultTV.setText("failed");
    }
    });
    }
  2. Update AutomatedUITest.java as :

    import android.support.test.filters.LargeTest;
    import android.support.test.rule.ActivityTestRule;
    import android.support.test.runner.AndroidJUnit4;
    import org.junit.Before;
    import org.junit.Rule;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    
    import static android.support.test.espresso.Espresso.onView;
    import static android.support.test.espresso.action.ViewActions.click;
    import static android.support.test.espresso.action.ViewActions.typeText;
    import static android.support.test.espresso.assertion.ViewAssertions.matches;
    import static android.support.test.espresso.matcher.ViewMatchers.withId;
    import static android.support.test.espresso.matcher.ViewMatchers.withText;
    
    @RunWith(AndroidJUnit4.class)
    @LargeTest
    public class AutomatedUITest {
    
    private String mEmail;
    private String mPassword;
    private String mSuccessMsg;
    
    @Rule
    public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(
    MainActivity.class);
    
    @Before
    public void initUserNamePassword() {
    mEmail = "codevscolor@gmail.com";
    mPassword = "password";
    mSuccessMsg = "success1";
    }
    
    @Test
    public void login_MainActivity() {
    
    onView(withId(R.id.editTextEmail))
    .perform(typeText(mEmail));
    
    onView(withId(R.id.editTextPassword)).perform(typeText(mPassword));
    
    onView(withId(R.id.button)).perform(click());
    
    // Check if the result is success or not
    onView(withId(R.id.textViewResult))
    .check(matches(withText(mSuccessMsg)));
    }
    
    }
Here , we are using ActivityTestRule to write this test.  Using this, the testing framework will launch the activity before each test method (@Test), Before test, it will run @Before method, and after test is completed, it will run @After and shut down the Activity.
 
To run this test, right click on “AutomatedUITest” -> Run “AutomatedUITest” -> select device or emulator and click OK.
 
This sample project is shared on Github. If you love this tutorial, do like codevscolor facebook page and subscribe to the newsletter. 🙂

2 Comment

  1. shrishail chanaveer says: Reply

    Hi do we need any AUTOMATED setup like apium to run these tests.

    1. nkaushikd says: Reply

      Hi, Apium setup is not required for these tests.

Leave a Reply