What is UI testing and why do we need it?

UI testing is required for every app we create. Before releasing the app into the market, it is one of the core process in mobile app development where we need to test how the functionalities can be accessed through the UI of the mobile app, irrespective of Android app development or iOS app development.

There are some required things that almost everyone in mobile app development domain considers during UI testing:

  • Check if the flow of UI interaction is correct as per the specifications or not.
  • Check if required functionalities can be used easily through the specified steps to or not.
  • Check if UI components behave as per the required standards or not.
  • Check if validation is done as per the standards for the user inputs.

How is the UI testing performed?

There are two ways available for UI testing:

  1. Testing by Human Tester
    This approach is adopted by the most naive software developers. It is always time-consuming, tedious and error-prone.
  2. Testing by Automated UI Testing Frameworks
    This is something that smart software developers adopt. There are various tools available which can be used for automated UI testing of the app. By using these tools we can easily test a large number of different test cases easily and quickly without human interaction.

Some frameworks available for Automated UI testing in Android are:

Testing UI for a Single App using Espresso

There are some steps which we need to follow for testing using Espresso:

STEP 1: Integrate Espresso in project using Android Studio.
STEP 2: Write different UI test cases.
STEP 3: Automate the UI test in real device/emulator.

Here is detailed explanation for the these steps.

STEP 1: Integrate Espresso in project using Android Studio.

To add Espresso in the project, add the following dependencies in the build.gradle of the app module.

dependencies {
    // App's dependencies, including test
    compile 'com.android.support:support-annotations:22.2.0'

    // Testing-only dependencies
    androidTestCompile 'com.android.support.test:runner:1.0.1'
    androidTestCompile 'com.android.support.test:rules:1.0.1'
    androidTestCompile 'com.android.support.test.espresso:espresso-core:3.0.1'
}

Add the following line in android.defaultConfig of build.gradle of the app module to setup instrumentation runner.

testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

After adding these lines to build.gradle, the complete file would look like this:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 26

    defaultConfig {
        applicationId "com.testapp"
        minSdkVersion 16
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
}

dependencies {
    // App's dependencies, including test
    compile 'com.android.support:support-annotations:22.2.0'

    // Testing-only dependencies
    androidTestCompile 'com.android.support.test:runner:1.0.1'
    androidTestCompile 'com.android.support.test:rules:1.0.1'
    androidTestCompile 'com.android.support.test.espresso:espresso-core:3.0.1'
}

STEP 2: Write different UI test cases.

Android Studio creates tests by default in src/androidTest/java/com.example.package/. In this package, you can create a JAVA class for writing test cases.

Before we start writing test cases, we need to understand the functions and annotations for the Espresso Java file:

Espresso has basically three components:

  1. ViewMatchers – allows to find view in the current view hierarchy.
  2. ViewActions – allows to perform actions on the views.
  3. ViewAssertions – allows to assert state of a view.

So, we can write the basic test case structure as following:

onView(ViewMatcher)            //finds the view
 .perform(ViewAction)          //performs the action on the view
   .check(ViewAssertion);      //validates the state of the view after performing the action

There are several ViewMatchers which you can choose as per your requirements:

onView(withText("Next"));

withText matcher will find the view with text “Next” inside the view hierarchy.

onView(withId(R.id.button_next));

withId matcher will find the view with the id “button_next” inside the view hierarchy.

You can also create the custom ViewMatchers using Hamcrest Matchers.

Following are the available ViewActions which are bundled with Espresso:

  • click(): Clicks on the view.
  • typeText(): Clicks on a view and enters a specified string.
  • scrollTo(): Scrolls to the view. The target view must be subclassed from ScrollView and the value of its android:visibility property must be VISIBLE.
  • pressKey(): Performs a key press using a specified keycode.
  • clearText(): Clears the text in the target view.

The ViewAssertions class provides a list of helper methods for specifying common assertions. The assertions you can use include:

  • doesNotExist: Asserts that there is no view matching the specified criteria in the current view hierarchy.
  • matches: Asserts that the specified view exists in the current view hierarchy and its state matches some given view matcher.
  • selectedDescendentsMatch: Asserts that the specified children views for a parent view exist, and their state matches some given view matcher.

To test a particular Activity using Espresso, we need to add the following line to configure the Activity for testing purpose:

@Rule
public ActivityTestRule<HomeActivity> mActivityRule = new ActivityTestRule<>(
           HomeActivity.class);

Rules are interceptors which are executed for each test method and will run before any of your setup code in the method. By creating this rule, we explicitly specify that we are going to test HomeActivity and its components in the automated test.

As we have got enough knowledge of Espresso testing functions, we can start writing the test cases as per the following instructions:

  • Add annotation @RunWith(AndroidJUnit4.class) before the class name.
  • Create a method with @Before annotation to initialize data which will be used in the test cases.
  • Create a method with @Test annotation to specifiy a test case. Here, you can use the components (matchers, actions and asserstions) we discussed above.

Let’s create an Espresso test for testing a simple functionality:

There are three view components on the screen: a Button, a TextView and an EditText. On click event of button, we set text of TextView by getting the text written in EditText.
Here, we want to test that, on clicking the Button after writing “LetsNurture” in the EditText, are we able to see “LetsNurture” written in TextView or not.

So, TextMatchingTest.java will look like this:

@RunWith(AndroidJUnit4.class)
@LargeTest
public class TextMatchingTest {

    private String mStringToBetyped;

    @Rule
    public ActivityTestRule<HomeActivity> mActivityRule = new ActivityTestRule<>(
            HomeActivity.class);

    @Before
    public void initValidString() {
        // Specify a valid string.
        mStringToBetyped = "LetsNurture";
    }

    @Test
    public void changeText_sameActivity() {
        // Type text and then press the button.
        onView(withId(R.id.editTextUserInput))
                .perform(typeText(mStringToBetyped), closeSoftKeyboard());
        onView(withId(R.id.changeTextBt)).perform(click());

        // Check that the text was changed.
        onView(withId(R.id.textToBeChanged))
                .check(matches(withText(mStringToBetyped)));
    }
}

STEP 3: Automate the UI test in real device/emulator

Now, its time to execute tests for getting results. To do so, just go to the test case method which you want to test. There you’ll see a run button on the left panel.

On Clicking on Run button, it will ask for the device selection, just like the normal app run.

Select the device connect through ADB, and click OK to start the test. This will install the app in the device, launch the specified Activity in the @Rule and perform the test automatically.
After completing the test, it will show test results in the run window at the bottom of the Android Studio.

Pretty much easy and interesting, Right?

I hope you will be able to start writing UI tests for your projects by referring this article. You can also refer https://developer.android.com/training/testing/ui-testing/espresso-testing.html for better understanding.

Kindly share your thoughts on this article by following us on Twitter by the username @letsnurture or you can also contact us if you submit your inquiry here.

Happy Coding! … and Testing 😉

 

Want to work with us? We're hiring!