Hello, World Unit Test
Before we go any further let’s look at a simple unit test. For demonstration purposes we can use the Add method from the Google Calculator example, which is available from https://github.com/googlesamples/android-testing, see Listing 1-1.
Listing 1-1: Add method from Google’s Calculator example
A very simple unit test is shown in Listing 1-2 which tests if the Add method can add two numbers correctly.
Listing 1-2: Test method for Add method from Calculator example
Unit tests use assertions to make sure the method provides an expected result. In this case we’re using assertEquals to see if the Add method returns 7 when adding 3 + 4. If the test works then we’ll should see a positive or green result and if it doesn’t then we’ll see a red result in Android Studio.
Understand the Benefits of Using an Agile Approach to Android Development
If you’re new to Agile development you’re probably wondering how Agile can improve the development process.
At its most basic Agile and unit testing in particular helps us to with the following
- Catch more mistakes
- Confidently make more changes
- Built in regression testing
- Extend the life of your codebase
If you write unit tests and they cover a significant portion of your code then you’re going to catch more bugs. You can make simple changes to tidy up the code or more extensive architectural changes, run your unit tests and if they all pass then you can be confident that you didn’t introduce any subtle defects. The more unit tests you write the more you can regression test your app whenever you change the code. And once you have a lot of unit tests then it becomes a regression test suite that allows you to have the confidence to do things you wouldn’t otherwise attempt.
Unit tests mean you no longer have to program with a ‘leave well enough alone’ mindset. You can now make significant changes, such as changing to a new database, updating your backend API, change to a new material design theme etc. and be happy that your app is behaving the same as before you made the changes if all the tests execute without any errors.
Explore the Agile Testing Pyramid for Android
There are several types of tests you need in your test suite to make sure your app is fully tested. You should have Unit Tests for the component or method level functionality, API tests for any backend RESTful APIs and GUI tests for Android activities and general application workflow.
The classic Agile Test Pyramid which first appeared in Mike Cohn’s book Succeeding with Agile. This is a good guide for the relative quantity of each types of tests your app is going to need.
Create Hello World Unit Test in Android
In the following example we show how to create our simple unit test example in Android Studio. This should return true assuming adding two numbers in the calculator Android app works correctly.
To set up and run a unit test you need to perform the following tasks
- Prerequisites – Android Plug-in for Gradle version 1.1.x
- Create the src/test/java folders
- Add junit:4:12 dependency in build.gradle (app) file
- Choose Unit Tests’ Test Artifact in Build Variant
- Create unit tests
- Right click on tests to run tests
Click on File->Project Structure and make sure the Android Plugin version is greater than 1.1. In Figure 1-2 the Android Plugin Version is 1.2.3 so we’re good to go.
Next we need to create the src/test/java folders to put our unit test code. For the moment this seems to be hard coded to this directory. So change to Project view to see the file structure and create the folders, see Figure 1-3. Alternatively in Windows create the folders using the file explorer or on a Mac use the command line on a terminal window to make the changes. Don’t be worried if the folders don’t show up when you go back to the Android view in Android Studio. They’ll show up when we change to unit tests in the Build Variant window.
Add junit library to the dependencies section in the build.gradle (app) file as shown in Figure 1-4.
Choose the Unit Tests test artifact in Build Variants and use the debug build, see Figure 1.5. The test code directory should now also appear when you’re in the Android view of your app.
Create the Unit Test code for our simple example. We need to import the org.junit.Before so we can create a Calculator object. We need import org.junit.Test to tell Android Studio that we’re doing unit tests. And as we’re going to do an assertEquals we also need to import org.junit.Assert.assertEquals, see Listing 1-3.
Listing 1-3: Unit test code.
Right click on CalculatorTest java file and choose Run ‘CalculatorTest’ to run tests, see Figure 1-6.
If your tests are successful they show as green and anything that produces an error is shown in red. All your tests should be green before you continue with any coding.
The real beauty of unit testing is that you don’t need an emulator or physical device to do your testing. But if we look back at our Agile Testing Pyramid we know that we’re going to need some GUI tests. Remember GUI tests are tests on Activities and unit tests are tests on individual methods in your code. We won’t need as many GUI tests as unit tests but we’re still going to have to test every activity for happy paths as well as not so happy paths.
When it comes to testing GUI we have a few frameworks that we can choose from, we can use the Android jUnit3 framework, Google’s Espresso, UIAutomator, Robotium or some Cucumber type Android framework such as Calabash. In this blog we’ll use Google’s Espresso as it’s quick and easy to set up and it also has support for Gradle and Android Studio. But we’ve used the other frameworks in the past and they are all have their benefits.
Espresso has 3 components, namely ViewMatchers, ViewActions and ViewAssertions. ViewMatchers are used to find a view, ViewActions allow you to do something with a view and ViewAssertions are similar to unit test assertions, they let you assert that the value in the view is what you’d expect or not.
Listing 1-x shows a simple example of an Espresso GUI test. We’re adding two numbers again, but this time we’re doing it by interacting with the GUI, not calling the underlying method.
Listing 1-4: Adding two numbers using Espresso
In this example
withId(R.id.operand_one_edit_text) is one of the ViewMatchers in the code and
perform(typeText(THREE)is a ViewAction. Finally
check(matches(withText(RESULT)) is the ViewAssertion.
Create Hello, World GUI Test
This time we show how to create our simple GUI test example in Android Studio. As with the unit test this should return true assuming adding two numbers in the calculator Android app works correctly.
To set up and run a GUI test you need to perform the following tasks
- Prerequisites – Intall the Android Support Repository
- Test classes are in the src/androidTest/java folders
- Add Espresso dependency in build.gradle (app) file
- Choose Android Test Instrumentation Test Artifact in Build Variant
- Create GUI tests
- Right click on tests to run tests
Click on Tools->Android->SDK Manager, click on the SDK tools tab and make sure the Android Support Repository is installed, see Figure 1-8.
By default Android Studio creates a src/androidTest/java folder when you create the project using the project wizard so you shouldn’t have to create any new directory. If you can’t see it then check the Test Artifact in the Build Variant window is set to Android Test Instrumentation, see Figure 1-9.
Add the following Espresso libraries, see Listing 1-5, to the build.gradle (app) file in the dependencies section and click the Sync Now link. Open the Gradle console as this may take a minute or two.
Listing 1-5: Espresso Libraries
The following code in Listing 1-6 shows how we set up and run the GUI test to add 3 + 4 and how we assert that this is 7.0.
Listing 1-6: Adding two numbers using Espresso
In the code we first connect to the Calculator Activity and then use the ViewMatcher and ViewActions to put the number 3 and 4 in the correct text fields. The code then uses a ViewAction to click the Add button and finally we use the ViewAssertion to make sure the answer is the expected 7.0. Note that the GUI displays the result as a double, so it’s 7.0 and not 7 as you might expect see Figure 1-10.
Results are shown in Figure 1-11. In this case they look very similar to the unit tests but it took a lot longer for the emulator to spin up.
In this post we looked at the current state of unit testing and GUI tests on the Android platform. In the next blog we’ll explore Agile testing in a lot more detail so you can see how to apply these techniques to your application to produce cleaner, faster code with less defects.
Note a complete set of these testing blogs have been compiled together into an Agile Android mini-book, published by Apress and available from Amazon
This is Part 1 of 6, the remaining blogs can be found below.
Part 1 – Agile Android Testing
Part 2 – Android Unit Testing
Part 3 – Hamcrest, JaCoCo, Mockito, and Jenkins for Android
Part 4 – Espresso Testing on Android
Part 5 – Android Mocking
Part 6 – Maintaining Someone Else’s Android Code