Testing in Android (MVP) – Part 3

In this last post of the three-part series on Testing in Android (MVP) we will go over how to add instrumentation tests that run on an Android device or emulator. If you have not checked out part 1 on unit tests or part 2 on integration tests, you should go back and check them out. Okay, let’s round off our series on testing in Android (MVP).

Setup your emulator for testing

In order to run instrumentation tests for our Android app we have to setup the emulator a bit differently than normal. When we run instrumented tests on an emulator of physical device we can’t wait for animations or network calls so we have to disable some animations.

Navigate to Settings | System | Developer options and disable all the animations.

If you haven’t enabled developer options, you can enable them by visiting Settings | System | About phone and tap the Build number until developer options are enabled. For additional reference visit the developer docs. Now that our emulator (or physical device) is all setup lets look at what dependencies we need to run instrumentation tests.

Dependencies in the app build.gradle file

Before moving forward we need to make sure to add the following testing dependencies to our build.gradle file to run tests with Espresso. Espresso is a UI testing framework for Android that allows us to find views and make assertions among many other things. For more information visit the link above but let’s focus on what dependencies we need to add.

Cool now let’s see what makes these tests useful.

Why Run Instrumentation tests?

Instrumentation tests will help us confirm our app shows data in a way that we expect based on our business logic. But wait… isn’t this what the integration tests do for our presenter? … Well yes, but instrumentation tests further confirm this since we can assert that a TextView contains some text, or that a Progress indicator is showing when data is loading.

Testing the View (Activity) from MVP

The first thing we need to do is create the test class. Let’s create a new Kotlin file and name it MainActivityInstrumentedTest.Kt. We need to add this into the androidTest folder of our project like so:

Next, let’s add a few annotations to the class. We need to tell the test runner we want to use the AndroidJUnit4 class so let’s add @RunWith(AndroidJUnit4::class) and then mark the test using @LargeTest annotation since we are running a large test. With all this setup we should have the following test class setup:

Finally, let’s create a rule for our test to launch the MainActivity by adding the following line:

Alright, we are all set up so let’s write our first test:

Perfect, you have written your first instrumentation test. Let’s press the run button next to the new method and see the green bar!

Nice work! Now let’s move on to the more difficult tests with the implementation of our custom keyboard.

Custom Keyboard instrumentation Example

Testing a custom keyboard is a non-trivial task so let’s see how we can do this. Well with any custom keyboard we need to use Espresso ViewMatchers to find our keyboard and then perform an action based on X and Y coordinates since we can’t find the views on the keyboard using their respective ids. So how does this look for our test?

Well, first let’s add a few helper functions for this to our test class. In the code snippet below we are adding a new method to click at an x and y coordinate within the view we have matched against (more on this in a bit). So here is what the code looks like:

It is important to note here the view we have, and the x and y position is relative to the View and not the entire screen. So we define the touch points in terms of the view we are matching against. Let’s look at the other helper method we need to add:

This method uses our keyboard default width percent and the row count to determine the coordinate x and y we want to press in the KeyboardView. Awesome so now let’s check out the test function to enter a price and hit the check button on the keyboard.

In the code above, we have called our getTargetXAndY() helper funtion and determined the point we want to single tap. From that target point we can interact with the other helper method clickXY passing in these target X and Y coordinates to hit the check button. Lets run the test and see that we can confirm we enter the price and then hit the check button.

Great job! We are finally done with our instrumentation testing for our tip calculator. The following is the end result with both the test method and the two helpers for full reference.

For additional content related to these keyboard tests check out my question and answer on StackOverflow.

Summary

Great job! You have just learned how to add instrumentation tests to your application and confirm the behavior of your application by using Espresso to assert that views on screen display the expected results when a tip is calculated. The full code for this tutorial is available on GitHub. This wraps up our 3 part testing series for MVP architecture within an android application.

If you enjoyed this tutorial please like, share or follow me on social. Don’t hesitate to leave a comment with any feedback!

 

Testing in Android (MVP) – Part 2

Integration Testing

Integration tests are important in Android so we can ensure the behavior of the integration between the view and the model work correctly. So how exactly do we write these integration tests since the presenter relies on 2 other objects the View & Model?

In the previous post, we added a new dependency to our project called MockK. What is MockK? Well, MockK is a mocking framework for Kotlin. A mocking framework allows us to verify the behavior of an object without having to build the objects from scratch among various other things.  More information about MockK can be found at the website.

So now we know about mocking frameworks let’s see how we use them to build out integration tests.

For brevity, I am only going to show how we use the mocking framework to write the integration tests although you can find the source code for the MainPresenter at the github page.

Annotations

Alright, so what have we done here?

With the property fields, you will notice some annotations, @RelaxedMockK, @MockK. These annotations provide use with mocked version of the classes they sit above. For example, @RelaxedMockK on the Contract.View class is setting up a mock object that is relaxed in nature.

From the docs:

Relaxed mock is the mock that returns some simple value for all functions. This allows to skip specifying behavior for each case, while still allow to stub things you need. For reference types chained mocks are returned.

Source

The @MockK annotation creates the standard version of the mocked object. This means we want to mock the class but will provide the behavior of the class when interacted with, however, we are passing it a parameter relaxUnitFun which tells the framework to allow functions returning Unit to be relaxed. In our case, this affects the setTipOption function which has no return value or Unit if you prefer to be explicit.

from the docs:

In case you would like Unit returning functions to be relaxed. You can use relaxUnitFun = true as an argument to mockk function, @MockKannotation or MockKAnntations.init function.

Source

Although we only use these annotations, MockK provides many other useful annotations that are worth looking into.

The Setup

Okay, so now that we have understood a bit about the annotations we are using let’s turn our attention to the setup method:

Here we, initialize the mocks and set up the model to return the values we want to use when interacting with the mock. Additionally, we tell MockK to init the annotated classes from above. Since this method is annotated with @Before it will run before every test is executed.

The Tests

These two tests that we set up above allow us to ensure the behavior of the start method in our presenter as well as the changeTipPercent method. We then use the verify lambda from MockK to assure the view has been interacted with in an expected way. That’s it! You now know how to use MockK to write a simple integration test. What happens though when we want to adjust the behavior of a mock after setup occurs?

Changing behavior with every

Each of the above methods has a line:

This line is altering the behavior of the computeTotalPrice function of our model so we can verify the other methods of the view are interacted with in an expected way. We can now verify that the displayFinalPriceWithTip function of the view is called as well as the displayError method when we pass in a bad value.

Summary

Wow, look at you go! You now know how to create an integration test for your presenter in the MVP architecture using MockK. In the last part of this testing series with the MVP architecture we will take a look at the instrumentation tests on Android for running tests on an Emulator or physical device. See you then!

If you enjoyed this post please leave a comment, like or share, and follow me on social media.

Testing in Android (MVP) – Part 1

In this first post of a three-part series, we will walk through unit testing an android application that uses the MVP architectural pattern. By the end of the three-part series, we will have discussed unit testing, integration testing, and instrumentation testing. The first two will allow us to run tests very quickly on our local development machine. For the third, we will need to set up an emulator or use a physical device to run the tests. This series will both show you the benefits of having chosen the MVP pattern as well as the various libraries and frameworks that help us write tests against this architecture.

Jumping Right In

Picking back up with the MVPDemo from the previous post, where we built a Tip Calculator app, we are now going to test our code.

Test our code? But that’s a waste of time, we have to ship!

With automating our unit tests we can provide:

  1. scale
  2. insurance
  3. peace of mind

In other words, with automated unit tests, we can ensure the code that we wrote last week does the same thing this week, even if someone else has committed a new feature.

The two-thirds Rule

In Android, we should test at least 2 out of the 3 things from the list below to ensure that our app’s core functionality works:

  • Unit tests – the smallest possible test we can write which asserts an actual value matches an expected value.
  • Integration tests – tests that ensure the proper integration of 2 or more components. (think presenter in the MVP pattern)
  • Instrumentation tests – tests that run on a physical or emulated device. These are not fast tests but they can be useful in a CI system or if you want to make sure things display as expected (asserting views are on screen or contain certain text, clicking this button performs this action, etc.).

Okay so now that we know the types of tests we should be writing let’s ask the real question…

Is there really a two-thirds rule?

Well, no. The point is you should consider covering the majority of your code with some tests. Being able to confidently know that two-thirds of the behavior of the code you have just written is guaranteed will drastically improve your process as an engineer and team member.

In my previous post, discussing the MVP architectural pattern, we can see how the decoupling of our code allows us to more easily test the functionality within our app. Specifically, we can see how the three test types we just mentioned apply to the MVP pattern.

As you can see, we can test the model with fast unit tests using either JUnit , AssertJ or Robolectric. We can test our presenter using a combination of AssertJ & MockK (Mockito if you prefer it too MockK). And finally, we can test our view code using the Espresso library or UIAutomator . These are just a subset of the popular testing frameworks available to us now but let’s get to the unit testing for this first part.

Setup

Before we get started we have some setup to take care of to import the correct dependencies for testing. In the top-level build.gradle file, add the following line (e.g denoted by the // 1):

and in your app level build.gradle file add the lines (e.g denoted by // 1, // 2 // 3):

  1. Adds the plugin for JUnit 5 to work with Android
  2. Adds the test/kotlin directory to our test source sets
  3. Adds the JUnit 5, AssertJ and MockK testing dependencies

Writing a Unit Test

One of the most important areas to test within our code base is our app’s model code. No, I am not talking about testing a POJO or POKO (Kotlin variant), I am talking about the Model used to manage the data within our application! The code that determines the actual behavior of the functionality provided for a view. We have to test this code to guarantee our app works as expected. But what does this look like?

MainModel code (for reference):

Looking at our model code we see it provides the following functionality for use:

  • MainModel() (default constructor)
  • setTipOption(position: Int) : Unit (sets the tip option and returns nothing)
  • computeTotalPrice(price: String?): Double (computes the price returns total)

Since we don’t have any constructor arguments lets start by assuring the setTipOption code works as expected. We want to assert that with a valid index, the tipOption is set to the expected value.

Okay, so what did we just do? Well, we set the tip option to 0 (the first index of the array in our model) which sets our tip to 5% so when we compute the total price of $100 check, we should expect that we get back a value of $105.0 for 5% of $100 = $5.

We have written our first passing test but if we run the same test with code coverage we will notice that we haven’t tested the full source code for this method. So, let’s take a look at one other test case: the invalid tip option. If you look back up at the MainModel code, we can see that if the index of the argument is out of range of valid tip options we default to a 20% tip. We will want to make sure that code works too!

Okay perfect all code within the setTipOption method is now covered and the behavior works as expected. Going forward, if any of the code in this method changes we now have a couple of tests to make sure we don’t break the expected behavior. If we do break the expected behavior (assuming a new feature or new default is chosen by the product team…), we will update the test case and move on. Additionally, we want to test out the functionality of the computeTotalPrice method.

Since this method is a bit more complicated we have to test it with at least 3 tests:

  1. Test that a good price will yield the expected result
  2. Test null or empty price yields 0.00 return value
  3. Test if we have a negative price that all values will be 0.00

Well done! 100% test coverage for a single class and the best part is in under 1 second we can now test that the MainModel code works as expected. As an exercise, write some tests to exhaust the tip calculator options testing the remaining percentages return the expected values.

All of the source code can be found on GitHub.

Summary

Great job! Now you know how to write unit tests that guarantee the behavior of your tip calculator’s model code. In this post, you have learned that there are 3 types of tests you should consider when it comes to Android application development. You have learned about some of the frameworks used in the testing process. And you have written your own unit tests.  In my next post, I will show you how to test the presenter code in the MVP pattern to guarantee the integration between the View and Model.

If you enjoyed this post please share or comment! And feel free connect with me on social media.

 

Best practices MVP in Android

Working with GUI applications is a lot of fun for a developer. We get to influence design and user experience as well as the end product for any given feature. This can be fun until a designer comes over and shows you something you know will be entirely custom or better yet, it is a complete redesign but you haven’t spent any time building an architecture in your company’s app. Uh oh! Get ready to cancel all your prior engagements, late nights and long days await. It doesn’t have to be like this though.

In most of my apps, I prefer to use the Model View Presenter (MVP) pattern although MVVM is basically the same idea (I am not talking specifically about the ViewModel from architecture components… but you can read more about that in my previous blog post). Okay, so what am I talking about.

Well, in the MVP pattern we have our three layers again:

  • Model – controls how we access and manage the data in our application
  • View – controls how we display that data in our user interface
  • Presenter – acts as a middleman between the view and the model

Alright great! Now we know what the three pieces are but how do we go about making this a real thing in our app? We are going to build out a simple tip calculator application using the Kotlin programming language and the MVP pattern.

Okay, so we see that when an action is performed via the user interacting with the view, the presenter uses its knowledge of the model to have it perform an operation, return the result and then display it back in the view. Let’s take a look at how we can adapt our code base to this pattern more closely though.

When designing the MVP pattern we should really consider what does our application need to do in terms of functionality. Since we are building a tip calculator this will be relatively simple to figure out.

With our Model we want to allow the following functionality:

  1. Set check amount
  2. Set a tip amount
  3. Compute the total price of the check including the tip

With our View we want to display the following:

  1. A TextInputEditText to collect the check total
  2. A ChipGroup with Chips to allow the user to choose a tip percentage
  3. A FloatingActionButton for the user to press to compute the total with tip
  4. An AppCompatEditText to display the total
  5. An AppCompatEditText to display the tip amount

And finally, with our Presenter we want to:

  1. Setup the initial View state
  2. Pass the tip percentage to the model when a Chip is checked
  3. Pass the check amount to the model and compute the cost of the total check with tip
  4. Tell the view to display the total and the tip amount

Now that we have the important stuff laid out we can start building out the different layers of the application.

The View is comprised of our MainActivity. Since we are developing a testable architecture though we will use interfaces to define the contract for the View and the Presenter. This may seem unnecessary now but in a later post, we can see how this architecture allows us to test our app on a JVM. We can start with the following Contract interface which wraps these two other interfaces like so:

 

Now let’s implement the interface and add the code for all the widgets to display the data from our presenter layer in our View.

Now since the MainActivity creates the Presenter lets look to see how it manages the View and Model as a middleman:

Finally, we can look at our Model code which handles the business logic of our application:

And that’s it! We have an app that uses the MVP architecture in the Kotlin programming language. As you can see the View is pretty dumb in that all it handles is displaying things to the user based on our presenter interacting with our mode. The best part about this architecture is that you can test it very easily which I will show in an upcoming blog post!

Please comment or share on social if this was helpful!

 

 

Using ViewModel and LiveData in your Android App

A common trap

Since the dawn of Android, application development has been a bit like the wild west. As developers, we want to build fast so sometimes we neglect the architectural design of our applications from the start. A designer hands off the UI and we go over the requirements for our project and start building. The MainActivity starts out lean but we create a bunch of objects for our business logic, hook into framework API’s to start services or leverage hardware from the device resulting in a 2K line file and error-prone code. But we can do much better by taking some extra time to think about separation of concerns within our application. The applications we are building should be modular, extensible and testable. So how do we accomplish this in GUI applications?

Loaded answer: developing an architecture for the application!

Popular GUI architectures:

All these patterns encompass similar concepts. The main idea is we have a Model that contains our business logic, which will be mostly Android agnostic so we can test the code we are writing without the framework dependencies. We have a View that is responsible for displaying information to the user and handling interactions from the user with the on-screen widgets. Finally, we have the ViewModel which is responsible for the display logic for our model (business logic) into the view. But what does that actually mean?

Things may become clearer with the following diagram:

The View is responsible for loading the layout, attaching listeners to UI elements as well as hooking into Android Framework APIs such as system services, custom service implementations, broadcast receivers, etc. Depending on the design choices the view will also be responsible for injecting dependencies or creating the dependencies for the other components in the design.

The ViewModel is responsible for facilitating communication between the view and the data access layer containing application state and business logic.

The Model will handle everything else related to the business decisions of the application including remote connections to REST APIs, data persistence for offline scenarios, and anything else that could be a business rule for the application.

Hopefully, this clears things up for now but if not don’t worry we are going to work through an example.

App Scenario

Let’s think about how we can accomplish the following task: Build an app that lets me search for places using a textual phrase using Google’s Places API. Cool project, I know! But how do we design this in a robust way?

Architecture Components!

In GUI applications there are plenty of design patterns to improve the design of our applications such as MVP, MVC, MVVM, as well as a few others. It has not always been easy to decide which to use when and there is certainly no silver bullet. It has become a common idiom though to use however, we have seen best practices emerge over time in building great apps from developers among the community and open source projects from companies across the world. It was only recently that Google took a stab at actually providing some built-in APIs on Android to help guide the architectural structure of our applications via Architecture Components but wow are they useful.

For our purposes, we are going to look into three components from the new libraries but only one will be the main area of focus.

  1. LifecycleOwner
    • Since the latest release of the support library, we now have activities and fragments implementing the LifecycleOwner interface. So we won’t have to worry about this too much for now but it is important to know it is needed for the ViewModel.
  2. LiveData/MutableLiveData
    • LiveData and MutableLiveData are generic data holder classes that can be observed within a life cycle. Remember LifecycleOwner? These objects allow the data they hold to be observed when changes are made. The distinction between the two, however, is that MutableLiveData exposes the setValue(T) and postValue(T) methods. This means we can change the underlying value and the UI will reflect those changes automatically if we attach an observer in which we update the view. There is also a way to attach an observer without a LifecycleOwner which you can read more about here but we won’t focus on that here.
  3. ViewModel (main area of focus)
    • ViewModel is a class that is responsible for preparing and managing data for an Activity or Fragment. It is where a developer can hook into the business logic and the best part is data outlives the life cycle of the Fragment or Activity it is used within. This means objects are not recreated everytime the screen rotates or your app is backgrounded(unless of course, the system kills your app to free up resources).

Architecture

So we have thought a little bit about the architecture of our app and we will implement the following:

  • Search screen to get user input through a form field
  • Search result screen to display the results
  • Detail screen to display more information about a search result
  • A repository which will make HTTPS request to the Google Places API using Retrofit
  • Business logic class (ViewModel) which will use the repository to get data and manage it

All source code is written in Kotlin and available on Github.

Let’s skip over the easy parts since we already know how to collect input from an EditText and pass it as an extra through a Bundle to a Fragment.

The Search Results Screen layout xml:

The important parts of the layout really are the Toolbar and the RecyclerView everything else is meant to improve the UI/UX.

Place List Fragment:

Note: important information is in the comments above. If you looked through this code you will notice using the MainViewModel we were able to request the places using the query from the extras and search the places API. We also attached a listener which allows us to update the UI when the request finishes.

Place Detail Fragment

If the comments weren’t enough the important thing to note here is since we are attaching the MainViewModel to the hosting activity of these two fragments we viewed the source of above we only need to re-attach to it and our data is still there. This means we can navigate to and from the same place from the list or list of places and the data will persist.

And finally, the MainViewModel

In the MainViewModel we have all our business logic nicely separated from the rest of our application. The MutableLiveData holder class around our PlacesResponse and PlacesDetailsResponse allow us to observe the changes applied to them when the rest call finishes.

Summary

As you can see LiveData and ViewModel are very powerful components that can help build better apps. Hopefully, this shows how powerful the LiveData and ViewModel classes are and convinces you to at least look into using them to help architect your application. In an upcoming tutorial, I will show you how we can test this code easily.

Please leave a comment or share if you enjoyed the tutorial.