Reliable Android Testing using LinkedIn’s Test Butler Tutorial
I’ll assume that if you’re reading this, you have some familiarity with writing instrumented tests in android. In particular, I expect that you know how to use Espresso.
What is Test Butler?
Test Butler is an android testing helper library that gives you the ability to have a reliable test environment on an Android device or emulator. It does this by stabilizing the emulator and handling changing global emulator settings. You can read more about it in this blog post and in the repo’s README.
To learn more about how to create a reliable android testing environment, check out this video which was the motivation for test butler.
Requirements and setup
- Before getting started, you will need an android emulator (running stock android) or a rooted android device. This is because the Test Butler apk can only be installed on a device which has elevated privileges (a.k.a rooted). To create an emulator with elevated privileges in Android Studio, open up the AVD Manager. When you get to the stage of choosing a
System Image, choose one from the Android Open Source Project (the ones without the Google APIs), as shown in the image below:
You can read more about creating and managing AVDs here.
- The next step is installing the Test Butler apk on your emulator. You can get it from here (navigate to files to find the apk). Once downloaded, you can drag it to your emulator or use adb (android debug bridge) to install it using this command:
adb install test-butler-app-2.0.0.apk
- You can then add test butler as a test dependency in your app’s
The problem with testing this is that you need a way of changing the network state to offline. It’s easy to turn the wifi on and off, but the device will still have the data connection which is more difficult to control programmatically. Another problem with doing this yourself is that you need to add permissions for changing network state to your
AndroidManifest.xml , but your app may not really need these permissions.
This is where Test Butler comes in. It comes bundled with all these permissions and you can just call it in your tests without having to declare them or write the code to handle the network changes.
- The first step is creating the test runner:
Add this as the
testInstrumentationRunner in your gradle file (Replace
<package-name> with the package the above file is in.
- The following is the test file (I’m showing only the relevant parts for this tutorial, you can find the rest of the file here):
The most important part is the
toggleConnectivity function. Here, I use the TestButler static methods
setGsmState (for the data connection) and
setWifiState (for wifi) to toggle the connectivity of the phone. Since these operations are asynchronous, I use the function
threadSleep() to wait for them to finish up (this isn’t the recommended way of doing this; check out Espresso idling resources for a better way).
In the main test
showsSnackbarWhenOffline() , I toggle the connection and swipe down to refresh the view (just in case some data had already been loaded). I then check that the Snackbar is shown with the expected text.
In this tutorial, I’ve shown how to set up test butler and a simple example of how to use it in your app tests. It has quite a wide range of capabilities and I encourage you to check out its repo and the LinkedIn blog post to see how it can be relevant to your project.
Finally, I’d like to thank Roger Taracha for encouraging me to write this blog post.
I hope you learned something, and any feedback and questions are welcome.