Android Testing

In order to deliver good quality products, we need to embrace Software Testing. This helps us identify bugs swiftly and verify that  our software is fit for use. 

Type of Tests

According to android documentation there are two types of tests.

Local unit tests

Individual elements are tests and everything else is mocked including the Android framework dependencies. An element is the smallest testable unit of the application. These tests are good for validating the business logic.  In Android, testing these units is not easy because the view (Activity or Fragment) is coupled with the model (business logic of the application). Separating the view from the model is essential if we want to make testing simple.

Instrumentation tests

Individual elements are combined and tests together as a group. The tests run on an android device or emulator. The emphasis here is to test user stories and to mimic user interactions in the app.

Local Unit Tests

In order to make unit testing simple, we have to consider separating the view from the model. To do this, let's consider the common design patterns that we have in Android.

Model View Controller (MVP)

Model is the underlying business logic, the view interacts with the user and the controller exposes the model to the outside world. It's important to note that the model is not the domain model (a java objects used to save and retrieve data from the database).

From the illustration above the view is not dumb because it can also communicate with the model. The lack of clear separation of concerns between the view and the model makes this design unsuitable for writing unit tests.


Model View Presenter (MVP)

This is similar to MVC above except that the presenter replaces the model. The presenter acts as a mediator between the model and the view. This means that the two components cannot directly communicate with each other. The view is dumb because it just recieves and sends instructions to the presenter. 

The clear separation of concerns between the view and the model makes this design pattern ideal for testing. Unit tests for the two component (Presenter and Model) is simply done by either mocking the view or the presenter.

Although MVP pattern is simple and easy to implement, there are various ways to do this. We have discussed this and came up with our customized version of MVP as OpenSRP developers. 

OpenSRP MVP Rules

  1. Create a contract (Java interace) for each concept and define interfaces for the view, model and presenter in the contract. 
  2. The three components should implement interfaces from the contract created in rule 1 above.
  3. In each component, reference the interface of the other component rather than the implementation.
  4. Model should be referenced in the Presenter and not the View.
  5. View should not be referenced in the Model.
  6. Avoid android dependencies in the Presenter.
  7. Use an interactor to make calls to the database or network layer i.e. using Async Tasks or Handlers.
  8. Interactor should sit between the Presenter and the model.
  9. Interactor should be initialized in the Presenter.
  10. All database calls should be made using:
    • Async tasks
    • Future tasks (We need a way of moving this from the main thread).
  11. Prester tests should mock the view and the interactor (If implemented).
  12. Model tests should mock the presenter.



We have created sample mvp applications that respect these rules in https://github.com/OpenSRP/opensrp-client-architecture/tree/mvp 

Please check them out and feel free to add your sample mvp application there.

Instrumentation Tests

These tests check how the application works in real life. They run on an android device or emulator. Running them before a release may be better than adding them to our continuous integration tool (Travis). This is because they take longer to execute compared to unit tests and may require external services (Server, Dabase) to be working correctly. 


The best way to write these tests is to automate QA checklist. The Quality Assurance team develop a checklist or testing scripts that they validate before a release. Automating the test scripts will reduce time spent manually testing everything and quickly identify regression bugs. 


Expresso has been idenfied as the tool to be used for automating the QA checklist.

References

https://developer.android.com/studio/test/

http://softwaretestingfundamentals.com/unit-testing/

https://en.wikipedia.org/wiki/Software_testing#Unit_testing

http://softwaretestingfundamentals.com/integration-testing

https://code.tutsplus.com/tutorials/an-introduction-to-model-view-presenter-on-android--cms-26162

https://code.tutsplus.com/tutorials/how-to-adopt-model-view-presenter-on-android--cms-26206

https://android.jlelse.eu/android-mvp-for-beginners-25889c500443

https://panavtec.me/say-goodbye-to-all-main-thread-problems-in-mvp