Posted on

Android Testing pt 3.1 | Espresso Tests, Automated Disabling Animations


android espresso tests

 

Finally, we’ve reached the Espresso part. I’m going to show you how to test remaining part of a ChatActivity and automating disabling system animations

Espresso Tests

There are many names Espresso testing can have: end-to-end, integrated, UI… In fact, you can test the whole app with Espresso, without any mocks, even using real networking. It won’t be a unit testing and it won’t be fast testing, But it will be easy to design those tests because they come from a user perspective

As for Espresso setup – everything is already there for dependencies if you created a new project with the latest Android Studio

One extra dependency is this


It has useful methods for interacting with support libraries like RecyclerView, which we use in this post

What’s Left To Test

Since Espresso tests aren’t the only, but rather the last part of us testing our ChatActivity, we don’t need many tests here. I must admit, my ChatActiivy isn’t much chat, rather a monologue activity, because it’s just me sending messages to myself, without any back end. But that’s enough for now

What’s left for this part is to test RecyclerView part, which is setting up RecyclerView.Adapter correctly and its correct implementation. We already know that parts for sending messages, adding messages to the ArrayList and notifying RecyclerView.Adapter is implemented correctly with our ChatPresenterTest and ChatActivityTest

I believe testing Adapter is possible with Robolectric as well

Large Tests

Espresso tests are instrumented and they lie in src/androidTest just like Medium tests.

One thing to consider: don’t name test classes with the same names, even if they’re in different directories (test/androidTest). For example, I had ChatActivityTest both in test and androidTest and when I run ChatActivityTest from androidTest – it did run the one from test

Here’s a test for RecyclerView.Adapter, it is an integrated test, because it involves several classes to work correctly and give the desired output


Matcher to find RecyclerView list items by containing text, used above


And my RecyclerView.Adapter implementation has nothing special, setup is pretty straightforward

Disable Animations

This is quite an important topic because for your tests to work correctly, you need to disable animations on your device, you can do it manually from Settings

android espresso tests

But having any kind of manual work in testing, which is in its code automated, is contradictory

In the official documentation, Google doesn’t explain how to do it automatically, because there’s isn’t any clean solution from Google yet

There’s a Gradle attribute added in one of the latest Android Gradle plugins, but it doesn’t seem to work yet


 

So here’re the options to enable/disable animations 

  • Using ADB commands during Gradle tasks
  • From the app itself

Using ADB

You can disable animations on your device with these commands


It’s possible to run them in a Gradle task.  Now we need to figure out how to automate that. What Gradle task starts Espresso tests?

android espresso tests

And run ADB commands right before and after this task. There’s one handy library which wraps these ADB commands in one Gradle task to disable/enable animations and Gradle solution to automate it would be this


The problem here is that you’d get animations disabled only if you start your Espresso tests from that particular Gradle task, but there’re other ways! For example by right clicking on test class

android espresso tests

Or by clicking any of these buttons

android espresso tests

And they don’t start connectedAndroidTest Gradle task at all

android espresso tests

 

Now compare it to the one if you call from ./gradlew connectedAndroidTest

android espresso tests

 

You can see that running tests via clicking green run buttons doesn’t use connectedAndroidTest task at all. Which is the way I always run my tests. So I understand that it’s possible for me to remember to start my tests only via a Gradle task, but then I’d need to document it and explain to other developers to do it exactly the same way! Otherwise, tests might fail

And we write software to automate/adapt to us, not the vice versa, so let’s look for other option

From The App Itself

This way is going to disable/enable animations on your device right from Java code. This approach needs a manifest permission


Since it’s just for testing, it doesn’t make any sense to include it in the release version. And since we for testing we use only debug Gradle builds – we can implement this using Android manifest merger. I created this AndroidManifest.xml in src/debug directory


You can see that there isn’t any application tag, nor any activities declared, that’s because everything is handled with Android manifest merger, this manifest file is just used to be put on top of default one (from src/main directory) and result into one final file

In debug build resulting manifest will be with permission, in release – without

Now we can get into the Java part. I looked for many code snippets online, most of them are ugly/don’t work. But this library does! And I’m using it. Once again, it requires manifest permission, which we fixed in the previous step

Setup is pretty simple



And updated test class


 

That’s it, now your animations will be disabled for tests automatically and enabled for everything else like before. And you can verify this library working correctly by adding a ProgressBar in your layout, it won’t be animated in tests only. Or using TestButler library’s method

Conclusion

Ok, the half of a post was me explaining how to disable animations automatically, but it’s important and it took me a while to come out with this more or less clean solution. It’s really hard to find anybody explaining clearly working end-to-end solution 

In the next post, I’m going to talk about how to use advanced Espresso stuff like Idle resources. You can get the source code here and don’t forget to subscribe!

Useful Resources

  • Novoda library. Handy Gradle wrapper for ADB commands
  • DeviceAutomationTestRule a library that I used in this sample and recommend
  • TestButler a library by LinkedIn for making testing reliable, disable animations automatically. Didn’t get the point of it, since it seems to work only with emulators. Used it for verification method