RSS

Android Automated UI Testing with Expresso (I)

25 Nov

I have been trying to write a few articles on Android automated UI testing for a long time, ever since my last job when we started experimenting using Expresso in our commercial Android App.

This article outlines the simplest UI testing with Expresso, with step-by-step snapshots for beginners to walk through.

simpleuitesting_activities

 

  • Create a new Empty Android Project in Android Studio
  • Add a new Activity, called MainActivity
  • Add 3 buttons as shown below:MainActivity
  • Add another three activities, each of which has a text view:
    ActivityA
  • Add below code to launch an Activity when one button is clicked:
    public class MainActivity extends AppCompatActivity  {
    
            private Button mButtonGotoActivityA;
            private Button mButtonGotoActivityB;
            private Button mButtonGotoActivityC;
    
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
    
                mButtonGotoActivityA = (Button) findViewById(R.id.goto_activity_a);
                mButtonGotoActivityB = (Button) findViewById(R.id.goto_activity_b);
                mButtonGotoActivityC = (Button) findViewById(R.id.goto_activity_c);
    
                mButtonGotoActivityA.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Intent it = new Intent(MainActivity.this, ActivityA.class);
                        startActivity(it);
                    }
                });
    
    
                mButtonGotoActivityB.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Intent it = new Intent(MainActivity.this, ActivityB.class);
                        startActivity(it);
                    }
                });
    
    
                mButtonGotoActivityC.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Intent it = new Intent(MainActivity.this, ActivityC.class);
                        startActivity(it);
                    }
                });
            }
        }
  • Run and test the application and make sure it works.

Now, we will start using Expresso to add UI testing.

  • Open module app’s build.gradle file, and add below lines to the dependencies section:
    androidTestCompile ('com.android.support.test.espresso:espresso-core:2.2.2') {
        exclude module: 'support-annotations'
    }
  • In the defaultConfig section, add below line:
    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner”

    The build.gradle file now looks as below:
    build-gradle

Create a new class in androidTest folder, name it TestMainActivityNavigation:

TestClass

Here two annotations are added, the first one tells JUnit to run it as Android instrumental test, and make the AndroidJUnitRunner class provided in the Android Testing Support Library as your default test runner.

@RunWith(AndroidJUnit4.class)
@LargeTest
The small, medium or large test annotation, can be explained as below, but is not important
in this simple case. Per the Android Developers blog, a small test should take < 100ms, 
a medium test < 2s, and a large test < 120s.
  1. Small: this test doesn’t interact with any file system or network.
  2. Medium: Accesses file systems on box which is running tests.
  3. Large: Accesses external file systems, networks, etc.

ActivityTestRule provides functional testing of a single activity. The activity under test will be launched before each test annotated with Test and before methods annotated with Before. It will be terminated after the test is completed and methods annotated with After are finished. During the duration of the test you will be able to manipulate this Activity directly.

Add below function to the test class:

/**
 * This function tests button click on "Activity A", then UI should go to the corresponding activity
 */
@Test
public void TestNavigateToA() {
    TestHelper.clickView(R.id.goto_activity_a);
    TestHelper.shouldSee(R.id.textView_aaa);
}

Here to helper methods are used:

public class TestHelper {
/**
 * This function asserts that the view with given id is displayerd/seen
 * @param viewId
 */
public static void shouldSee(@IdRes int viewId) {
        onView(withId(viewId)).check(matches(isDisplayed()));
    }

/**
* Click on a view, e.g. a button
* @param viewId
*/
public static void clickView(@IdRes int viewId) {
onView(ViewMatchers.withId(viewId)).perform(click());
}
}

These functions uses Expresso functions to access views with specific ID, or perform certain functions such as Click(), or check if a view can be seen etc. To clearly see the UI test result, some delays are added in between each test.

Hover the mouse over the test class, where the double arrow is shown:

DoubleArrow

Click on it, you will be prompted to create run the test in Debug or Release configuration:

RunTest

Click on one of them, and a new configuration will be added to the toolbar of AndroidStudio, and the test will be then run on the connected devices:

RunTest2

All the test methods annotated with @Test in the class will be sequentially executed, as shown in the animation in the beginning of this blog.

Happy testing.

 
Leave a comment

Posted by on November 25, 2016 in Android

 

Tags: , , , ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: