adessoTurkey / ios-boilerplate

iOS boilerplate app that showcases architecture and libraries used at adesso Turkey
47 stars 5 forks source link

Data Mocking Analysis for Network #13

Closed akayrak-adesso closed 4 years ago

akayrak-adesso commented 4 years ago

Possible networking data mocking frameworks should be analyzed.

akayrak-adesso commented 4 years ago

Network stubbing (generally speaking) is made with various way;

  1. Creating an external local fake/mock server
  2. Creating an in-app in-memory local server
  3. Intercepting and stubbing network request before it goes out from network layer

All of these methods have their own pros and cons against each other.

Common sides

Nearly all libraries for these methods provide responses via file, JSON data, or with hardcoded strings. All cover various response status codes. All provides delay for requests, but some libraries make the delay endpoint base, some make it run instance base. Nearly all covers dynamic responses, which means for different request query, the same endpoint responses differently.

Info & Maintaining

External one means one more application and project, that we need to deal with (-), beside the mobile app. It may or may not be written in swift. Being a distinct project makes it more flexible (+) to do the stuff we may need. However, maintaining it with new endpoints may be neglected because of its being not in eyesight and need of all the time (-).

Discuss: Is it possible to have a swift mac-os server in the same workspace with our app?

In-app in-memory local servers are, as its name applies, in the same project with the mobile application, running locally on the device within the app. Maintaining them would be easier than external ones cause they are on eye-sight an also eligible to write unit tests in the workspace for its existence (+). For the tests, there are two approaches to create it. One is for just initing the necessary endpoint and request for the test. The other is initing all requests from one single point. First approaches maintaining would be higher (-) than second; because may init the same request multiple times for different places. But the second approach maintaining requests' cost is nearly the same for the external server's cost (+).

Interception method is kinda different than the others. With this method, the requests are not going out from the network layer; they are stubbed before. The maintenance cost is the highest (-). Although the stubbing looks very similar to the previous method's initing necessary requests for that test, it has a couple of drawbacks. If you are using a framework other than Alamofire or URLSession, there is no specific solutions/library for that stubbing. You have to stub manually that calls (-).

Usage Areas & Drawbacks

External local server method is both for general usage (+) while developing application when we do not have or have limited access to the backend system, and while making unit and UI tests with mock services (+). The local server's being of completely different process from the mobile application, there will be no memory, thread, or any other app-wide related problems.

In-app In-memory local server method is mostly used in UI and Unit testing (+). I think that it is also possible for general use but haven't seen anybody using it in that way. As this method is integrated within the application, it will use the same device resources. So it may have a bit creates performance issues on the edge cases.

The stubbing method is only for testing, not for general usage. Stubbing does not actually simulate whole network connections, so it may have resulted in overlooking some problems.

One other aspect of drawbacks is the approaches' code penetration with the app's non-test code base. The external approach has only the IP/address of the localhost (+) in the app's code, to point the server. In-app server's however, have its complete code (-) base may be resulted in sending it to production release. For the third option, stubbing has nearly no integration (+) with the non-test part of code.

Result

Before proceeding to a deep examination of possible tools/libraries, we need to decide the approach first.

akayrak-adesso commented 4 years ago

When we examine in-memory servers written in Swift that can run on iOS along with an app, we can find lots of libraries in various sizes. But we will examine 5 of them which are either just popular or backed by corporate companies.

Ambassador by Envoy, Shock by JustEat, SwiftLocalhost, Swifter, and Kitura - by IBM.

Kitura was a very popular and high demanded library until 2019. But IBM pulled its support from it by the end of last year. So we have to eliminate Kitura because it may become idle very soon and community support is uncertain right now.

Let's move to compare the others.

Ambassador is supported by Envoy and be actively used in the company's projects on UI testing. Shock is supported by open-source supporter company JustEat. They have created it from just their need, it is pretty much simpler and smaller than others. SwiftLocalhost is one person supported framework. It is simple and small like Shock, with a couple of different features. Swifter is kinda big brother here with 72 contributors and much bigger community than the others'.

Here below is a comparison chart for these four libraries.   Ambassador Shock SwiftLocalhost Swifter
Same endpoint Different Request Method No Yes Yes Yes
Lazy Response JSON File No Project Resource Path No Computer File Path
Parameter as Input on File Response N/A No N/A No
Parameter as Input on Custom Data Response Yes N/A Yes Yes - A bit of work
Delay Yes No Manual - sleep on data Manual - sleep on data
Community - Star 141 14 54 3000+

You can find examples of request handling with these libraries in this gist.

https://gist.github.com/akayrak-adesso/577924a9919ad9abc216f0024f756256

firatyenidunya commented 4 years ago

@akayrak-adesso Great work!!

akayrak-adesso commented 4 years ago

We have decided to use Swifter.