How to test Android Apps

Testing

We started building a new Android app, based on a previous version with reliability issues. Even with a tight deadline, we wanted to make sure we covered it with a pragmatic test suite.

Easier said than done. In the last two months we've been learning a lot about Android architectures and testing. There are many different tools, for different purposes (a good thing, but confusing for someone who's starting). Those tools are evolving fast, and documentation gets left behind, generating confusion. The Android framework itself is not optimally designed for testing. But things are definitely improving.

With this article, we're starting a series of How to test Android Apps articles. The goal is to help make testing more common in Android development. Which increases the chance that the next project we get already has tests in place.

Configuration

The latest versions of Android Studio come with built-in testing support. There's build variants: Unit Tests and Android Instrumentation Tests. You can switch them on the left menu:

 
Switch test Build Variants
 

But you can only have one active at a time. What are the differences?

Unit Tests

Plain tests that don't need Android to run, they run on the local machine JVM.

Test classes are placed in /app/src/test/java/com.example/. Dependencies are added on the gradle file with testCompile. You'll need to add jUnit:

testCompile 'junit:junit:4.12'

And here's a test example:

public class StringTest {
    
    private String string;
    
    @Before
    public void configString() {
        this.string = new String("test");
    }
    
    @Test
    public void testLevel() {
        assertTrue(string.equals("test"));
    }
}

Tests are marked with the @Test annotation. You can use @Before and @After to run code around each test, and @BeforeClass and @AfterClass to run code around all tests inside the test class.

More info: Building Local Unit Tests.

Android Instrumentation Tests

Unit tests that need Android components and Instrumentation tests. To do functional tests, like a real user. They run on a device or an emulator.

Test classes are placed in /app/src/androidTest/java/com.example/. Dependencies are added on the gradle file with androidTestCompile. Here's a simple unit test example.

public class EmailPatternTest extends AndroidTestCase {
    
    private Pattern emailPattern;
    
    @Override
    protected void setUp() throws Exception {
        super.setUp();
        this.emailPattern = Patterns.EMAIL_ADDRESS;
    }
    
    public void testEmailPattern() {
        assertTrue(pattern.matcher("[email protected]").matches());
    }
}

Which one to use?

If you only need unit tests, go with the first option. Tests start much faster, since it doesn't upload and install the app on a device every time. But if you need integration tests as well, go with Android Instrumentation Tests, to avoid switching build environments. That's what we did.

There's also a popular way to run instrumentation tests without a device, Robolectric, which we'll cover later on.

Next up, we will talk about Architecture. It influences how easy testing your application will be.


How to test Android Apps

  1. Introduction
  2. Architecture
  3. Unit Testing
  4. Instrumentation Testing
  5. Other details
TechSérgiotesting, how to