Testing for Android Intents Using Espresso
When developing applications for Android, it is important to be able to write tests to see if Intents fire or not. Previously, the concept of Intents created obstacles in testing. Android Espresso test support libraries provide ways to test parts of the application a lot more easily. There is an espresso-intents library specifically for testing Intents. With it you can test what Intents were fired on the device, and what extras they were sent with.
To start testing using Espresso, you first need to include the dependencies in your project. In addition to the basic Espresso setup, you need to add espresso-intents to your
// set up espresso androidTestCompile 'com.android.support.test:runner:0.3' androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2' // include espresso-intents androidTestCompile 'com.android.support.test.espresso:espresso-intents:2.2'
In your test, you start by making a call to
init() from Intents. This will start recording the fired Intents, and is required before each test where you want to verify Intent activity.
For each time you call
init(), you must follow it up with a call to
release() at the end of the test. This will clear the
Intents state and stop recording intents.
Now that we are set up to start recording intents within a test, we can verify that the correct ones are being fired. In this case we want to test that the
LoginActivity is launched if there are no existing accounts. This way we can be sure that a user can’t access the app without having an account set up.
After the call to
init(), we set it up so there are no accounts, and used ActivityTestRule to start our activity. We chose to use ActivityTestRule over IntentsTestRule so we would have the choice to delay the starting of the activity. If you choose to use IntentsTestRule, keep in mind that it will automatically start your activity, and make the calls to
release() for you at the beginning and end of each test, respectively.
Intents.init(); AccountUtility.removeAccounts(); rule.launchActivity(new Intent());
We can next use
intended() with a
Matcher passed to it to assure that the Intent was fired, or not fired, as expected.
hasComponent() will return a Matcher that will match Intents with the given class name. This is one of multiple IntentMatchers that can be used.
Espresso-intents also gives us the ability to see if an intent launched x number of times. You can do this by including the number of times it should launch in the
intended() call. In our case, if there is already an account, the
LoginActivity should not be launched.
intended(hasComponent(MainActivity.class.getName())); intended(hasComponent(LoginActivity.class.getName()), times(0));
Full code is available here.
Espresso-intents is a useful tool when creating tests for your Android application. To complement your tests confined to a single activity at a time, you can test the flow of your activities and test when Intents are fired. In addition to everything we’ve done here, Espresso also allows us to stub Intents, and test for their extras. Adopting this practice of testing Intents into your Android tests should help you to create a more complete test suite for your application.
Google recently released a long-awaited new version of Espresso (known as v2.0 now). Even the first version sparked some noticeable interest among test automation community, it seems that the second version is a great improvement and should be definitely checked out by everyone who uses Espresso as their test automation framework.