Espresso simple UI test

suggest change

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

Feedback about page:

Feedback:
Optional: your email if you want me to get back to you:


Writing UI tests:
* Espresso simple UI test

Table Of Contents
2 Gradle
5 Intent
17 Service
19 WebView
31 SQLite
35 Glide
37 Dialog
38 ACRA
44 Handler
53 Toast
63 Menu
65 Picasso
70 Volley
71 Widgets
78 Realm
90 Spinner
93 Writing UI tests
95 OkHttp
108 TextView
109 ListView
111 Loader
118 Xposed
119 Security
121 ImageView
123 Doze Mode
130 Drawables
131 Colors
134 Fresco
139 AdMob
145 Keyboard
146 Button
150 EditText
155 Vk SDK
163 ExoPlayer
169 XMPP
175 OpenCV
177 Threads
184 ORMLite
186 TabLayout
190 LruCache
192 Zip files
194 Fastlane
199 FileIO
202 Moshi
210 VideoView
216 Paint
218 ProGuard
226 CleverTap
228 ADB shell
229 Ping ICMP
230 AIDL
234 Context
240 JCodec
242 Okio
249 FuseView
254 Looper
261 Fastjson
263 Jackson
267 Smartcard