Introduction to Automated Android Testing – Part 5

In this series of blog posts, we are working through a sample app called Github User Search. Parts 1 – 4 covered why we should test, getting set up with testing, creating API calls and creating a presenter. Take a look at the previous posts as part 5 is a continuation of the series.

In part 5, we will take a look at interacting with the Presenter  created in part 4 and we will create the UI to display the list of search results.

Creating the UI

For the User Interface we want a simple list that displays the avatar, name and other user information in the list.

In part 4, we defined a View contract which the Activity should implement. This is where the Android specific code will be located (things such as visibility changes or any UI changes will be located here). To refresh your memory, this is the View contract we created in this last post:

Let’s implement the View! [adwords_square]

  1. Create a class called  UserSearchActivity. This class will implement the UserSearchContract.View contract and extend AppCompatActivity. Define a variable called userSearchPresenter of type UserSearchContract.Presenter. This is the object that we will interact with in order to perform our network calls.

    In onCreate(), create the presenter object. Provide it with the User repo defined in the Injection class. Pass the io() scheduler and the AndroidSchedulers.mainThread() scheduler so that the RxJava subscriptions know which threads they should perform their work on.

    On the next line, you can see I call userSearchPresenter.attachView(this) . This attaches the view to the presenter, so that the presenter can notify the view of any changes. Because the presenter isn’t aware of the activity’s lifecycle, in onDestroy() we need to inform the presenter that the view is no longer in existence, so we should then call userSearchPresenter.detachView(). This will unregister any RxJava subscriptions and prevent memory leaks from occurring.

  2. Create activity_user_search.xml in the layout folder. This will contain a RecyclerView, a ProgressBar, an error TextView and a Toolbar. I am using ConstraintLayout to design my screen, so I won’t go into too much detail as it is mostly drag and drop. (If you want to read more about ConstraintLayout check out my blog post about it here)UserSearchActivity

  3. We also need to add a SearchView to the toolbar so we have somewhere to type. Add a menu_user_search.xml file to the menu resource folder. Inside it, you will need to add a SearchView:

  4. We need to create a layout that will be used for each item in the RecyclerView. Create a file named list_item_user.xml in the layout folder. I used ConstraintLayout with one ImageView for the avatar and two TextViews.List_item_user_designmode

  5. Now that we have all the layouts we need, let’s tie the XML to the Activity. First, in onCreate() we will get references to the views we need.

  6. We need to hook the SearchView up into our activity to make it trigger the presenters search() method. In the onCreateOptionsMenu(), add the following code:

    This will inflate the correct menu, find the search view and set a query text listener. In this case, only when someone presses submit on the keyboard, we will respond by calling the search presenter with the query. We could do it in onQueryTextChange too but due to rate limiting on the Github API I will stick to onQueryTextSubmit. By default, the item will be expanded.[adwords_square]

  7. Next, we will implement the callbacks that the presenter will call when the items are finished loading.

    We are basically just toggling visibility of views here and setting the usersAdapter  to the new items that the service returned.

  8. For completeness, here is the UserSearchAdapter class which is used for the RecyclerView on the activity:

     

    Injection class

  9. Now if you run the app, you should be able to search for a username on Github and see results.github_user_search

Yay! We have a working app. Code for this post can be found here. In the next part, we will look at writing UI tests for the app. Make sure you subscribe so you don’t miss a post!

Subscribe to Blog via Email

Enter your email address to subscribe to this blog and receive notifications of new posts by email.


If you enjoyed this blog post, please consider buying me a cupcake to support future blog posts.

[buy_cupcake]

Introduction to Automated Android Testing – Part 4

In this blog post series, we are working through an example Android app called Github User Search. In the previous blog posts, we took a look at setting up your app for testing, creating API calls and writing the first basic test for the API transformations. Read part 1, part 2 and part 3 first.

This post will look at creating a presenter which communicates with the repository and conveys information to the view. This will also include writing unit tests for the presenter. The sample github repo this blog post will be working from can be found here.

Creating the Presenter

  1. In order to get started, create base interfaces called MvpView and MvpPresenter. All MVP functionality will extend these two interfaces.

  2. Create a BasePresenter. This will provide functionality to check whether a view is attached to the presenter and a way to manage RxJava subscriptions.

    As you can see above, there is a CompositeSubscription defined in the presenter. This object will hold a group of RxJava subscriptions. The detachView() method calls  compositeSubscription.clear() which will unsubscribe from all subscriptions, prevent memory leaks and view crashes (code will not run when the view is destroyed as it is unsubscribed). When a subscription is created in a presenter that subclasses this object, we will call addSubscription()
  3. Create the contracts between the view and the presenter in a class called UserSearchContract. Within this class, create two interfaces one for the view and one for the presenter.

    In the view, there are 4 methods, showSearchResults()showLoading(), hideLoading(), showError(). In the presenter, there is a method called search().

    A presenter does not care about how a view shows the results, nor how it shows an error. Similarly, a view doesn’t care how a presenter searches as long as it uses those callbacks to notify, the implementation doesn’t matter. [adwords_square]

    Separating the logic between the view and presenter is simple. Think about reusing the presenter for another type of UI and that will make you realise where the code should live. For instance, if you had to use Java Swing, your presenter can remain the same in that case, only your view implementation would differ. This helps you to place logic by simply asking yourself the question: Would the logic in the presenter make sense if I had a different type of UI?

  4. Now that the contracts between the view and the presenter are defined. Create/navigate to UserSearchPresenter. This is where a subscription to the UserRepository will be created, which will call the Github API.

    Here the presenter extends BasePresenter  and implements the UserSearchContract.Presenter contract defined in step 3. This class will implement the search() method.

    Using constructor injection allows easy mocking of the UserRepository when trying to do unit testing. The schedulers are also injected into the constructor, as the unit tests will always use Schedulers.immediate() but in the view we will use different threads.

  5.  Now for the implementation of search() :

    First off, run checkViewAttached() this will throw an exception if the view is not attached when the method starts running. Then tell the view that it should start loading by calling  showLoading(). Create a subscription to  userRepository.searchUsers(). Set subscribeOn() to the ioScheduler variable as we want these network calls to happen on the IO Thread. Set observeOn()  the mainScheduler  as we want the result of this subscription to be observed on the main thread. Then add the subscription to our composite subscription by calling addSubscription.[adwords_square]

In the onNext() method, handle the result by calling hideLoading() and showSearchResults() with the list of users returned by the API. In onError(), stop the loading and call showError() with the exception’s message.

Here is the full code for UserSearchPresenter :

Writing Unit Tests for the UserSearchPresenter

Now that the presenter is defined, let’s create some unit tests for it.

  1. Select the UserSearchPresenter class name. Press “ALT + Enter” and select “Create Test”. Select the “app/src/test/java” folder as this is a unit test that requires no Android dependencies.  The resulting location of the test is the following: app/src/test/java/za/co/riggaroo/gus/presentation
  2. In the UserSearchPresenterTest, create the setup method and define the variables needed for testing.

    By creating a mock instance of  UserRepository and the UserSearchContract.View we will ensure that we are only testing the UserSearchPresenter. In the setUp() method, we call MockitoAnnotations.initMocks() . Then create the search presenter with the mocked objects and immediate schedulers. Call attachView() with the mock view object as the presenter works only once a view is attached.
  3. The first test will test that a valid search term has the correct callbacks:

    This test asserts that: Given the user repository returns a set of users, when calling  search() on the presenter, then the view methods showLoading() and showSearchResults() are called. This test also asserts that the showError() method is never called.
  4. The next test is one that tests the negative scenario if the UserRepository throws an error:

    This test is testing the following: Given the userRepository  returns an exception, when calling search()  then showError() should be called.
  5. The last test we will add will assert that if the view is not attached, an exception will be thrown.
  6. Let’s run the tests and see how much test coverage we have. Right click on the test name and click “Run tests with coverage”Unit Test Coverage from the Presenter Test

We have 100% Coverage of the UserSearchPresenter! Yay!

The next blog post will cover creating the view and writing tests for the view. Make sure you subscribe so you don’t miss the next post in this series!

Subscribe to Blog via Email

Enter your email address to subscribe to this blog and receive notifications of new posts by email.


If you like my work, please consider buying me a virtual cupcake to keep the blog posts coming!

[buy_cupcake]

References:

This post series was based on a couple of implementations of MVP that can be found around the web. For reference, these are some of the articles used to get to this solution:

Introduction to Android Testing – Part 3

In the previous two blog posts I covered how to get setup with testing in Android and we created a sample app that we will be continuing to develop in this blog post. If you missed those two posts, I suggest reading part 1 and part 2.

In this post, we will look at getting a list of users from the Github API and writing unit tests for it. We will be starting from the following repo at this checkpoint.

Create Web Service Calls

To consume the Github API we will be using Retrofit and RxJava. I am not going to explain RxJava or Retrofit in this series. If you aren’t familiar with RxJava, I suggest reading these articles. If you haven’t used Retrofit before I suggest reading this.

In order to get a list of users for a search term, we will need to use the following endpoint (I am also applying a page size of 2 for this demo because of API call limiting):

To get more user information (such as a user’s bio and location), we need to make a subsequent call:

  1.  To start consuming these endpoints, we should create the JSON objects that they are returning and include them in our project. I normally generate them online here. Let’s create the following classes:  User class and UsersList class:


    Once the models are created, navigate to the GithubUserRestService. This is where we will create our Retrofit calls.

    The first network call will perform a search to get a list of users and the second network call will get more details about a user.[adwords_square]
  2. Navigate to  UserRepositoryImpl. This is where we will combine the two network calls and transform the data into a view that will be used in the front end. This is using RxJava to first get a list of users for the search term and then for each user it does another network call to find out more of the user’s information. (If you had implemented this API by yourself, I would try make one network call return all the required info – as discussed in my Reducing Mobile Data Usage Talk).

    In the above code, I am creating an observable by using Observable.defer() , this means that the observables code will only run once it has a subscriber (Not like Observable.create() which run when it is created). As corrected from the comments below, Observable.create() is an unsafe RxJava API and it shouldn’t be used.

    When there is a subscriber, the githubUserRestService  is called to search with the searchTerm  provided. From there, I use concatMap  to take the list of users, emit them one by one into a new observable that then calls githubUserRestService.getUser() for each user in that list. That observable is then transformed into a list of users.

    A retry mechanism has also been defined on these network calls.  retryWhen() will retry the observable when an IOException is thrown. An  IOException is thrown by Retrofit when a user has no internet (you might want to add a terminating condition such as only retrying a certain number of times).

    You might notice that I am using lambda expressions in the code, you can do this by building your app with the new Jack toolchain. Read about how to enable building for Java 8 on Android here.

    Now we have a repository and two network calls to get a list of users! We should write tests for the code we have just written.

Unit Testing – What is Mockito?

In order to unit test our repository object, we are going to make use of Mockito. What is Mockito? Mockito is an open source testing framework for Java released under the MIT License. The framework allows the creation of test double objects (mock objects) in automated unit tests. (Wikipedia).

Mockito allows you to stub method calls and verify interactions with objects.

When we write unit tests, we need to think of testing a certain component in isolation. We should not test anything beyond what that class’ responsibility is. Mockito helps us achieve this separation.

Okay, let’s write some tests!

Writing Unit Tests for UserRepositoryImpl

  1. Select the  UserRepositoryImpl class name and press “ALT + ENTER”. A dialog will pop up with the options to “Create Test”. Select that option and a new dialog will appear:Create Test Dialog
  2. You can select to generate methods but I generally leave the options unselected. It will then ask you to select a directory where the test should be placed. Select the “app/src/test” directory as we are writing a JUnit test that does not require an Android ContextSelect Test Directory - Automated Testing Android
  3. Now we are ready to set up our unit test. To do this, create a UserRepository object. We will also need to create a mock instance of GithubUserRestService as we won’t be directly hitting the API in this test. This test will just confirm that the transformations are done correctly within the UserRepository.  Below is the code to set up our unit tests:

    The method that is annotated  @Before will run before any unit test and it ensures that the Mock objects are setup before trying to use them.  We call MockitoAnnotations.initMocks()  in the setUp()  method and then create an instance of the UserRepository  using the mocked out github service.[adwords_square]
  4. The first test we will will write will test that the GithubUserRestService  is called with the correct parameters. It will also test that it returns the expected result. Below is the example test I have written:

    This test is split up into three sections namely: given, when, then. I separate my tests like this because it ensures your tests are structured and gets you thinking about the specific functionality you are testing. In this test, I am testing the following: Given the Github service returns certain users, when I search for users, the results should return and transform correctly.

    I find naming of tests is also quite important. The naming structure I like to follow is the following:

    [Name of method under test]_[Conditions of test case]_[Expected Result]

    So in this example, the name of the method is searchUsers_200OkResponse_InvokesCorrectApiCalls() . In this test case, a  TestSubscriber is subscribed to the search query observable. Assertions are then done on the TestSubscriber  to ensure it has the expected results.

  5. The next unit test will test if an IOException  is thrown by the search service call then the network call will be retried.

    In this test, we are asserting that the githubUserRestService  was called twice and the other network calls were called once. We also assert that there were no terminating errors on the subscriber.

    Final Unit Test Code for UserRepositoryImpl

    I have added a few more tests than the ones described above. They test different cases but they follow the same concepts as described in the previous section. Below is the full test class for UserRepositoryImpl :

Run the Unit Tests

Now after writing these tests, we need to run them, see if they pass and see how much of the code is covered by tests.

  1. To run the tests you can right click on the test class name and select “Run UserRepositoryImplTest  with Coverage”Run unit tests with coverage
  2. You will then see the results appear on the right hand side of Android Studio. Code Coverage Report - Unit test Android Studio

We have 100% unit test coverage on our UserRepositoryImpl  class. Yay!

In the next blog post, we will take a look at implementing the UI to display the set of search results and writing more tests for that. Be sure to subscribe so you don’t miss the next blog post in this series!

Subscribe to Blog via Email

Enter your email address to subscribe to this blog and receive notifications of new posts by email.


If you enjoy my posts, please consider buying me a cupcake to keep them coming.
[buy_cupcake]

Links:

Defering observable code until subscription in RxJava

RxJavas retryWhen() and repeatWhen()

Github user search app on Github

Introduction to Automated Android Testing – Part 2 – Setup

In this series of posts we are going to look at an Introduction to Automated Android Testing. In Part 1 of this automated testing series, we covered why you should write tests, where the test folders are located and the different types of tests you get in Android.

In this post, we are going to go over the typical structure and setup of your Android app in order to enable testing. I will be creating a simple app from scratch in this series and walk through each step of my thought process. The app we will be creating is a simple app that searches the Github API for users. Below is a rough mockup of what we will be creating:

Android Automated Testing Sample App

We will be starting from scratch. If you follow the steps below, you should end up with the repository that looks like this.
[adwords_square]

Getting started with a new app

  1. Open up Android Studio, select “Start a new Android Project”.
  2. Call the project “Gus” (Github User Search – original I know 😂) and company domain “riggaroo.co.za” . This will create a package name – za.co.riggaroo.gus . Click next.Step1 Automated Android Test Project
  3. Next choose the versions of Android you wish to support (I generally don’t go lower than API 16. You will cover 95.2% of users if you choose API 16 and above). Select API version 16 and click “Next”. Step 2 Automated Android Test Project
  4. Select “Empty Activity” and click “Next”.Step 3 Automated Test Project Android
  5. Change the name of the activity to UserSearchActivity  and the layout file to activity_user_search. Click “Finish”.Step 4 Naming default user activity.
  6. If you run the app – you should see a blank activity like below.Step 4 Blank App

Adding Test Dependencies

Navigate to your apps build.gradle  file and add the following dependencies. The  testing dependencies that need to be added include Espresso, Mockito, PowerMock and Hamcrest. Retrofit, OkHttp, RxJava and RxAndroid will also be added so we can do effective networking and achieve cleaner code.

testCompile  is the configuration for unit tests (located in src/test) and androidTestCompile is used for the instrumentation tests (located in src/androidTest). Differences between these two types of tests can be found in Part 1 of this series.

Using Gradle Build Flavors to enable Mocking

In order to enable easy and quick testing of the UI, we won’t be hitting the production APIs for Github. We will mock out responses and emulate different network responses. There are a couple of different ways to achieve this. The way in which I will demonstrate this is by using Gradle product flavors.

Flavors allow you to build different versions of your app, with some source code differences or resource differences. For instance, if you wanted to make a free version of your app and a paid version with more features, using product flavors would be a good way to achieve this.

In this instance, we will create a “Production” and a “Mock” flavor. We could also add a “Staging” flavour if we had a staging environment that we wanted our app to point to. This would allow us to install a production version of your app on a device at the same time as a mock version.

  1. In order to use productFlavors, navigate to your app build.gradle file and add the following into the android{ } section. The following code means that for the mock variant, the applicationId will be different which means I can install both concurrently on one device. For the prod version, the applicationId will be taken from the defaultConfig setting.
  2. Invoke a Gradle Sync and then on the left hand side of your IDE, you should see a “Build Variants” tab. Open it to see the different flavors of your app that are now available. Gradle Build Variants Android Studio

If you select a different variant, when you click run the build that is deployed to your device will be using that variant’s source set and applicationId .

[adwords_square]

Running the Unit Tests

In order to run the default unit test ( ExampleUnitTest) that exists within the project, you can do it in a few ways:

  • Within Android Studio navigate to and right click on the app/src/test/java  folder. Click “Run Tests”.Running Unit Tests with JUnit in Android Studio
  • Using Gradle: in terminal you can run  ./gradlew check

Running the Instrumentation Tests (Requires device or emulator)

In order to run the default instrumentation test ( ExampleInstrumentationTest) that exists within the project, you can do it in the following ways:

  • Using Android Studio navigate to and right click on the app/src/androidTest/java  folder. Click “Run All Tests”.Run connected tests android studio
  • Using Gradle: in terminal you can run ./gradlew connectedAndroidTest

How to structure your code to enable easy testing

In order to enable easy testing I am going to use Dependency Injection. You can achieve this without any frameworks (which is what I mostly do) but a lot of people advocate for using Dagger 2 to achieve it. This blog post series is not going to use Dagger.

Create these classes in the following folder structure:Simple Structure Of Android App

I have 4 top level folders for the different parts in the app. This can get more complicated the bigger your app gets. These are the basic folders I like to create:

  • presentation – Within this folder, I create subfolders and group functionality by feature. In this case, I created a folder called search which will hold the view and presenter for the search screen. It will also contain adapters and any other view related code for the search screen.
  • data – This will contain the repositories that will fetch data from the Github API.
  • model – Contains the models that will be used on the presentation layer and the ones that come from the service calls.
  • injection – Classes that will be used for Dependency Injection.

We have covered the setup of the sample app, how to run the different types of tests and the folder structure we will follow. This has now set us on a good path to ensure we can write tests for our app. If you want to see the result of this blog post, check out the corresponding completed code for this blog post here.

The next blog post in this series will go into detail about implementing the feature with tests. Don’t forget to subscribe so you don’t miss the next one!

Subscribe to Blog via Email

Enter your email address to subscribe to this blog and receive notifications of new posts by email.


If you enjoy my posts, please consider buying me a cupcake to keep them coming.
[buy_cupcake]

Thanks to @JoshLiebe for proofreading this post.

Introduction to Automated Android Testing – Part 1

I’ve seen a lot of people confused and unsure about how to do tests in Android. In the past, it was very difficult to test Android apps and there wasn’t much direction. In this series, I am going to try make testing a bit easier for you. This first post is just to get you started with testing, the next few will go more in depth into testing in Android. Let’s get started!

Android Testing

Why should I test anyway?

You probably don’t really need convincing, since you are already reading this blog post. Here are some reasons why I like to write tests:

  • Testing forces you to think in a different way and implicitly makes your code cleaner in the process.
  • You feel more confident about your code if it has tests.
  • Shiny green status bars and cool reports detailing how much of your code is covered are both consequences of writing tests.
  • Regression testing is made a lot easier, as automated tests would pick up the bugs first.

Regression testing is the biggest benefit for me. If you refactor and your tests still pass, you will be confident that you haven’t broken anything. The problem with testing is that you might not see the benefit of testing immediately, as the true value will only surface a couple of months later when you need to refactor.

What types of testing are there in Android?

Unit Testing

A unit test generally exercises the functionality of the smallest possible unit of code (which could be a method, class, or component) in a repeatable way.

Tools that are used to do this testing:

  • JUnit – normal test assertions.
  • Mockito – mocking out other classes that are not under test.
  • PowerMock – mocking out static classes such as Android Environment  class etc.

UI Testing – Instrumentation Tests

A UI Test or Instrumentation Test mocks typical user interactions with your app. Clicking on buttons, typing in text are some of the things UI Tests can complete.

Tools that are used to do this testing:

  • Espresso –  Used for testing within your app, selecting items, making sure something is visible. 
  • UIAutomator – Used for testing interaction between different apps.

There are other tools that are available for this kind of testing such as RobotiumAppiumCalabashRobolectric

What do I need to get started with Automated Testing?

In order for you to get started with automated testing in your app, you should follow some kind of architectural pattern that will help you test and structure your app in a clean, testable way. One such pattern that easily enables testing is Model View Presenter (MVP) for Views and Repository Pattern for Networking and Database Access.

Of course, this is not the only option for you as an Android Developer, it is one of the many that you can explore in order to get test coverage and a clean architecture.


I have found it very difficult to implement tests without having a defined structure, often my tests were useless and I didn’t know what to test, it was also very difficult to get code coverage on large apps. My UI tests were also not very reliable as they were testing against production servers. Hopefully we can address these issues in this blog series.

Structure your App in a Testable Way

Here is a diagram depicting the structure I will use as a guideline for the rest of the blog post series:

Basic Structure Of Android App that will allow for Automated Testing

  • Views  – Activities and Fragments. This is where we set text and make UI changes. I typically like to keep the Android specific code in this section and try not to pass a context further than the view, obviously this is not always easy but it is good guidance to try follow. Views should only talk to presenters.
  • Presenters – This is where business logic to decide what should be displayed on the views is going to go.  Presenters talk to the repositories to get information out, and convey information to the Views. Try avoid putting Android specific code in your presenter if you can avoid it as it will make unit testing more difficult.
  • Repositories – Decide where to get data from, should they come from local persisted data? Or should the data come from the network? Repositories talk to presenters.
  • Models – Typically POJOs, these are models that are used by the Presenter and the View to convey information to the View from the Presenter.

Unit tests will test the Presenters and the Repositories. UI Tests will test the View all the way down to the repositories.



There are many great articles describing MVP and other architecture options – this blog post is not going to go into those details. Read more about different Android architectures here, here and here.

Where are Automated Tests placed in my Android app?

In your Android app folder structure, there are two folders that will house the tests:  test  and androidTest

Automated testing in Android

androidTest  – Android Instrumentation Tests are located here. The tests in this folder need to run on an Android Emulator or physical device.

test/ – Unit tests are placed in this folder. Unit Tests run on the JVM on your local machine and do not run on an Android device or emulator. This means they do not have access to Android classes (such as the Context  class).


Now that we are aware of the different kinds of tests and where to place in them in our apps. The next post we will go deeper into how to structure your code in order to allow for better unit testing. Check out Part 2 here!

Make sure you get notified about the rest of the series by subscribing to updates.

Subscribe to Blog via Email

Enter your email address to subscribe to this blog and receive notifications of new posts by email.