I saw this Reddit discussion on Android testing concepts, which tries to categorize tests into short, medium and long. I don't find that a very useful way to think about different types of tests, so I thought I'd give offer my view.
Two dimensions
I think it's more useful to think of tests in two dimensions
- Does it run on the JVM or needs a device?
- Does it test the UI or not?
Depending on the answer to these two questions you get 4 types of tests.
JVM tests
JVM tests are the faster to run since you don't need to deploy to a device (physical or emulator), and should be preferred. Try to structure your app so that the logic is in pure Java classes i.e. does not use the Android framework.
Since we are writing Android apps, it is difficult to test the UI without the Android framework. There are two ways you can do that.
Robolectric
The first way to test the UI on the JVM is Robolectric, which mocks the Android framework. I don't recommend that, because the mocked classes don't necessarily reflect the actual behavior on the Android framework.
Model-View-Presenter (MVP)
The second way is to make your Android classes as logic-free as possible. There are various architecture patterns you can use to achieve that, for an example Model-View-Presenter (MVP). MVP allows you to encapsulate the Android part inside the View (Activity or Fragment) and extract the logic into the Presenter, which does not use any Android framework code. This way, you can test the Presenter on the JVM.
Espresso
After you have tested your logic extensively on the JVM (you may want to aim for 100% test coverage), you should add some UI tests. Think of these as sanity checks, going through the happy path to make sure the app does not crash when you bump up the library version. I use Espresso for UI tests, together with Mockito and MockWebServer to set up a hermetic environment for repeatable tests.
More info