Essential Android Testing UI with Espresso edit forum

Espresso simple UI test

UI testing tools

Two main tools that are nowadays mostly used for UI testing are Appium and Espresso.

| Appium | Espresso | | —— | —— | | blackbox test | white/gray box testing | |what you see is what you can test|can change inner workings of the app and prepare it for testing, e.g. save some data to database or sharedpreferences before running the test| |used mostly for integration end to end tests and entire user flows|testing the functionality of a screen and/or flow| |can be abstracted so test written can be executed on iOS and Android| Android Only |well supported|well supported| |supports parallel testing on multiple devices with selenium grid| Not out of the box parallel testing, plugins like Spoon exists until true Google support comes out


How to add espresso to the project

dependencies {
  // Set this dependency so you can use Android JUnit Runner
  androidTestCompile 'com.android.support.test:runner:0.5'
  // Set this dependency to use JUnit 4 rules
  androidTestCompile 'com.android.support.test:rules:0.5'
  // Set this dependency to build and run Espresso tests
  androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'
  // Set this dependency to build and run UI Automator tests
  androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.2.2'
}

NOTE If you are using latest support libraries, annotations etc. you need to exclude the older versions from espresso to avoid collisions:

// there is a conflict with the test support library (see http://stackoverflow.com/questions/29857695)
// so for now re exclude the support-annotations dependency from here to avoid clashes
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2') {
    exclude group: 'com.android.support', module: 'support-annotations'
    exclude module: 'support-annotations'
    exclude module: 'recyclerview-v7'
    exclude module: 'support-v4'
    exclude module: 'support-v7'
}
// exclude a couple of more modules here because of <http://stackoverflow.com/questions/29216327> and
// more specifically of <https://code.google.com/p/android-test-kit/issues/detail?id=139>
// otherwise you'll receive weird crashes on devices and dex exceptions on emulators
// Espresso-contrib for DatePicker, RecyclerView, Drawer actions, Accessibility checks, CountingIdlingResource
androidTestCompile('com.android.support.test.espresso:espresso-contrib:2.2.2') {
    exclude group: 'com.android.support', module: 'support-annotations'
    exclude group: 'com.android.support', module: 'design'
    exclude module: 'support-annotations'
    exclude module: 'recyclerview-v7'
    exclude module: 'support-v4'
    exclude module: 'support-v7'
}
//excluded specific packages due to https://code.google.com/p/android/issues/detail?id=183454
androidTestCompile('com.android.support.test.espresso:espresso-intents:2.2.2') {
    exclude group: 'com.android.support', module: 'support-annotations'
    exclude module: 'support-annotations'
    exclude module: 'recyclerview-v7'
    exclude module: 'support-v4'
    exclude module: 'support-v7'
}

androidTestCompile('com.android.support.test.espresso:espresso-web:2.2.2') {
    exclude group: 'com.android.support', module: 'support-annotations'
    exclude module: 'support-annotations'
    exclude module: 'recyclerview-v7'
    exclude module: 'support-v4'
    exclude module: 'support-v7'
}

androidTestCompile('com.android.support.test:runner:0.5') {
    exclude group: 'com.android.support', module: 'support-annotations'
    exclude module: 'support-annotations'
    exclude module: 'recyclerview-v7'
    exclude module: 'support-v4'
    exclude module: 'support-v7'
}
androidTestCompile('com.android.support.test:rules:0.5') {
    exclude group: 'com.android.support', module: 'support-annotations'
    exclude module: 'support-annotations'
    exclude module: 'recyclerview-v7'
    exclude module: 'support-v4'
    exclude module: 'support-v7'
}

Other than these imports it is necessary to add android instrumentation test runner to build.gradle android.defaultConfig:

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

Device setup

For non flaky test it is recommended to set following settings on your devices:

Quite a setup from the real world ha? Well now when thats out of the way lets take a look how to setup a small test

Writing the test

Lets assume that we have the following screen: The screen contains:

Now lets create a class that will test our flow:

/**
* Testing of the snackbar activity.
**/
@RunWith(AndroidJUnit4.class)
@LargeTest
public class SnackbarActivityTest{
    //espresso rule which tells which activity to start
    @Rule
    public final ActivityTestRule<SnackbarActivity> mActivityRule = 
        new ActivityTestRule<>(SnackbarActivity.class, true, false);
@Override
public void tearDown() throws Exception {
    super.tearDown();
    //just an example how tear down should cleanup after itself
    mDatabase.clear();
    mSharedPrefs.clear();
}

@Override
public void setUp() throws Exception {
    super.setUp();
    //setting up your application, for example if you need to have a user in shared
    //preferences to stay logged in you can do that for all tests in your setup
    User mUser = new User();
    mUser.setToken("randomToken");
}

/**
*Test methods should always start with "testXYZ" and it is a good idea to 
*name them after the intent what you want to test
**/
@Test
public void testSnackbarIsShown() {
    //start our activity
    mActivityRule.launchActivity(null);
    //check is our text entry displayed and enter some text to it
    String textToType="new snackbar text";
    onView(withId(R.id.textEntry)).check(matches(isDisplayed()));
    onView(withId(R.id.textEntry)).perform(typeText(textToType));
    //click the button to show the snackbar
    onView(withId(R.id.shownSnackbarBtn)).perform(click());
    //assert that a view with snackbar_id with text which we typed and is displayed
    onView(allOf(withId(android.support.design.R.id.snackbar_text), 
    withText(textToType))) .check(matches(isDisplayed()));
}
}

As you noticed there are 3-4 things that you might notice come often:

onView(withXYZ) <– viewMatchers with them you are able to find elements on screen

perform(click()) <– viewActions, you can execute actions on elements you previously found

check(matches(isDisplayed())) <– viewAssertions, checks you want to do on screens you previously found

All of these and many others can be found here: https://google.github.io/android-testing-support-library/docs/espresso/cheatsheet/index.html

Thats it, now you can run the test either with right clicking on the class name / test and selecting Run test or with command:

./gradlew connectedFLAVORNAMEAndroidTest

Table Of Contents
39 ACRA
64 Menu
93 Testing UI with Espresso
112 Loader
119 Xposed
132 Colors
135 Fresco
140 AdMob
147 Button
156 Vk SDK
170 XMPP
176 OpenCV
200 FileIO
203 Moshi
217 Paint
231 AIDL
241 JCodec
243 Okio
255 Looper
  ↑ ↓ to navigate     ↵ to select     Esc to close