Do you feel intimidated when it comes to testing your Android Apps? Does Server Dependency as the main source of flakiness always scare you?
Have you leveraged Dependency Injection, Repository Pattern, MVP or MVVM pattern and using fakes or mocks to make your code highly testable but still feel something is incomplete.
Do you have a legacy code base and wonder if there could be a way to efficiently test it without having to do even a slight refactoring. Well then you are at the right place.
Server Dependency as the Main Source of Flakiness
The main source of flakiness for a production level app is the Server Dependency. So it becomes very important to mock the response from the server in order to test your android code with respect to that response. Following are some of the approaches.
1.) Mocks for Unit Testing using Mockito
2.) Fakes for Integration Testing
3.) Mocking Server Response at Http Level using WireMock, MockWebServer
Testing the Presentation Layer is of Utmost Imporatnce
Many experts say that testing the business logic in your ViewModel/Presenter should be given a high priority. But a typical ViewModel does nothing but simply pushing data from a data source to the presentation layer.
Ultimately Android is a FrontEnd Framework. In the end are the Views(Activities, Fragments etc.) which get shown to the user.
Testing views can assure us that what gets shown to the user is correct and we can also infer to a great extent that the previous layers are working fine but vice-versa is not true.
Setting Up WireMock
In the build.gradle file of your app set up Wiremock by adding the following dependencies.
Screen To Test
We have a screen where we are hitting https://api.blockchain.info/charts/market-price?timespan=1weeks api to get the bitcoin rate for the last week and plotting the data on a chart as follows.
Integrating WireMock in the Test class
In order to set the port no. on which wire mock would run you need to add WireMockRule.
Changing BaseUrl to localhost
I am using an interceptor to change the baseUrl of Retrofit Client to localhost(http://127.0.0.1:8080/) while testing.
Dummy Json Files
You can use dummy Json files as mock responses. For that create an asset folder for the debug source set and add the json files there.
Stubbing network Calls
I have a stubber class where all the stubs are created and maintained to have separation of concerns.
if we see stubWeeklyBitCoinResponse(), we are changing the base url using BaseUrlChangingInterceptor.
Then using stubFor method, we are telling the HTTP layer, whenever /charts/market-price api gets called a dummy response as defined in bitcoin_rate_response.json should be thrown.
in stubBitCoinRateResponseWithError we are throwing a response with a specific error code to do negative testing.
We can also introduce delay in our response in the following way.
We can also throw faults in our responses.
We can throw the following faults using Wiremock.
In this test we are testing if Y values of the chart are labelled properly or not. In onCorrectResponse_checkIfChartYDataValuesAreCorrect() following things are happening :-
1.) Right before loading the activity, we are stubbing “/charts/market-price” to give a successful response as this api gets called when the fragment is attached to the activity.
2.) Loading the activity.
3.) checkYLabelling() checks that the Y Values in the dummy Json response are correctly mapped to Y entry of the LineChart.
For every error code, we are displaying a different error message to the user in a different fragment. The following tests, check if correct error message is displayed or not.
Conclusion and Takeaways
- ) You can achieve quite efficient and accurate testing using WireMock and Espresso without having to refactor your legacy code.
- It is said, the more real dependencies you add to your tests, more flaky your code becomes. But using WireMock you can help you involve the network layer as well during testing leading to more realistic tests without adding flakiness.
- Testing of errors, exceptions also becomes very easy.
1.) Following is the talk by Sam Edwards where he explains in detail the advantages of WireMock.
Follow me on twitter, for more updates. https://twitter.com/akapil167