Mocking API Calls in UI Tests

Beyza Ince
Trendyol Tech
Published in
4 min readMay 25, 2021

Testing process is essential in the Trendyol iOS application. It helps us to increase maintainability and reduce the possibility of feature problems. There are various kinds of user scenarios in application UI but it is hard and time-wasting to cover all of them with manual testing. So we give importance to automated UI Tests to verify that those scenarios are completed as intended.

Why Do We Mock API Calls

We realized that our UI Tests fail not only in our code changes but also in errors or unexpected responses in API calls. To eliminate API calls errors, we decided to mock API calls while executing our tests. Besides this, we realized UI Tests have many dependencies and their maintenance cost is high. So, we decided to mock API calls only for Smoke Tests. ( If you are not familiar with Smoke Tests concept, you can read Hazel Turan’s article)

Swifter Integration in Project

There are different open-source projects to mock API calls. We decided to use Swifter because of its easy integration and ease of use. You can access a lot of information in Andres Pisa’s article.

Swifter, starts local server inside the app with default 8080 port and it lets us to define which request call must return which JSON response.

We made some changes to start mocking API calls inside of the application while UI Tests are running.

If you want to access something inside the application during tests run, the only way is to use launchEnvironment and ProcessInfo. We add a variable to launchEnvironment before starting UI Tests and we get this variable inside the application with ProcessInfo.

launchEnvironment["MOCK_DATA_ENABLED"] = "1"

The most important part is to check the URL inside of the Network class. First of all, we need to guarantee that this control is not available for the Store scheme. Because, this scheme is for only App Store and we know that UI Tests will never run when this scheme is selected. After that, we control whether the ProcessInfo object has the key that must be added when only UI Tests running. If this key has value, then URL returns localhost:8080.

We hold the JSON objects that we want to return from the local server as JSON files. To make an easy setup, we create a new JSON array file that includes every request’s URL, method and response’s JSON file name. With this way, when we need to add a new service request, all we have to do is to add this request’s URL , method and response’s JSON file name inside this JSON array.

Before starting UI Tests, we read JSON array with the code below and for every object in this JSON array, we call setupStub function.

By using setupStub function, we kept the JSON response in the method choosen inside the local server.

We have different usages for different responses inside the same view. When we set service response, this response can only cover one usage. If we want to run UI Tests with a different response, then we should override same request with a different response after setup.

Parallel Testing

Running UI Tests sequentially takes a long time. To decrease test time, we enabled parallel testing option. This enabled us to start clone simulators at the same time and running tests in parallel but resulted in local server error.

We realized that, this error was caused by the parallel testing. Each clone simulator tries to start local server with the same port (8080). To solve this problem, we made some changes in starting local server.

We started the local server with different port and we set port number to SERVER_PORT key in launchEnvironment to access inside the application.

launchEnvironment["SERVER_PORT"] = "\(BaseTestHelper.shared.dynamicStubs.portNumber)/"

We accessed the port number in ProcessInfo.

ProcessInfo.processInfo.environment["SERVER_PORT"] ?? "8080/"

In conclusion, thanks to Swifter, we managed to run UI Tests with mock API calls. If you have any questions, do not hesitate to leave a comment below 🙂. Thank you for reading!

--

--