UI Testing with Kakao & Testing REST APIs Using MockWebServer

Caner Gulgec
Armut Labs
Published in
5 min readJan 26, 2021

--

User Interface(UI) testing ensures that your application satisfies the functional requirements and works as intended. They are normally written using Android native testing framework which is Espresso but in this post, I will show you how to write UI tests with Kakao and mock REST API responses.

Kakao is a library which is built on top of Espresso. It provides Domain-Specific-Language(DSL) for writing UI tests much more readable and understandable than Espresso.

When your application makes API calls throughout the lifecycle of it, testing UI components can be inconsistent. To make the tests reliable, you need to mock the application’s network layer. Here comes the MockWebServer to the rescue.

MockWebServer is a library that allows you mock the behavior of the remote server without making call over internet. With this way, you can implement different test scenarios easily.

UI Testing at Armut 🍐
As an android team at Armut, we are aware that writing UI test is essential
in terms of improving the application’s quality and increasing the testing process because as you might guess, our application has many complex scenarios that no one can test manually and continuously before implementing UI tests. And, I must admit that sometimes we were spending too much time on it. Also, after start writing tests we minimized the time spent on finding potential bugs related to UI in the application.

Now, let’s dive into code! Add the following dependencies to the app-level Gradle file. Make sure to use the latest versions of them.

Every project has some kind of base URL that you might refactor before implementing MockWebServer. To do that, create a function to get the base URL in your application class. Then, simply access it in RetrofitModule to use it. ( I did not add the whole class implementation)

However, we have a problem! As we are using a mock server, we should not use the real base URL, instead, we need to change it with our local URL.

testRunner is the solution for this case. It allows us to configure our test environment and add the new conditions we set for our test cases.

  • To achieve this, create a new test application class in androidTest directory to change the base URL with localhost.
  • Then, create a custom testRunner to use MovieTestApp in our test classes instead of MovieDbApp.

newApplication method returns an application class that we provide for our tests.

  • Open the app-level Gradle file and change testInstrumentationRunner implementation with your custom testRunner.
testInstrumentationRunner "com.android.test.utils.MovieTestRunner"

Now, before moving on to writing tests, we should mock responses that remote API returns from the server. To do so, you need to make an API call and get the success response body in JSON format as we are testing this case. Copy the response and create a file named success_response.json. The sample response could be like this:

After creating JSON response, create assets directory in-app module and put the JSON file there.

You need to find a way to read the JSON file because MockWebServer cannot read it directly. To read the file, we need to create a helper class. The goal of this class is simply writing JSON file contents in a String.

You know that API calls are asynchronous operations and we need to make UI tests wait until the response comes from the server. We will be using Idling resources for this scenario. Now, create a test class in androidTest directory.

@LargeTest annotation is not mandatory but recommended in UI tests. It states that the duration of the test can be greater than 1 second

@Before annotation states that it will run before every test.

@After annotation states that it will run after every test.

We have to start the mock server before each test and stop it after completing the tests. Put mockWebServer.start(port) inside setup method which will start mockServer on the port specified. Do not forget to stop it on the cleanup method.

OkHttp3IdlingResource is a class that controls Kakao to wait until the OkHttp client completes its task. OkHttpProvider is another helper class that provides static OkHttp instance.

For our test case, we should tell mockServer which response to return. To do that, paste the following code inside the test method.

setResponseCode returns response code. You can change it as you wish for different scenarios like testing error cases.

setBody returns the body of the response. In this case, we are reading our JSON file with FileReader class.

Note: What if you have multiple API calls in your application and need to return a different responses for each request. Then you need to edit the dispatcher a bit.

When you write tests with Kakao, you need to create a class that inherits from Screen which involves views in the interactions of the tests. Now, create MovieScreen class in androidTest directory. In this scenario, I will check whether the second RecyclerView item is visible on-screen or not.

Finally, we can check whether our test case is successfully implemented or not. Replace the MovieFragmentTest with the following:

activityScenario launches the activity before running test methods.

As you can see, we can easily access the view references in MovieScreen and verify that the second RecyclerView item name is visible or not. Now, just sit back and run your test method.

You can access the full source code below the repository.
Happy Coding!

References
* Subhrajyoti Sen — Testing Rest APIs Using MockWebServer
* Special thanks to Engin CAN

--

--