Building a Convolutional Neural Network based Dog Breed Classifier

Can modern Deep Learning approaches be used to build an algorithm that detects dog breeds based on a given input image? Can the Convolutional Neural Network (CNN) achieving this task be build up from…

Smartphone

独家优惠奖金 100% 高达 1 BTC + 180 免费旋转




Android UI testing with mock data

For a business to excel, its product must promise quality. This means to not only exceed the expectations of the market, but continuously deliver a customer experience that redefines and increases the standards of said product. When speaking in terms of software products, quality assurance is achieved through testing.

Testing applications simplifies their maintainability and reduces the chances of defects. An especially important component to test for apps is their user interface (UI). UI tests assess the different scenarios in which a client may use an application and rely on data to determine if the correct UI is being displayed. This data can be created manually. The benefit of this is that a greater range of scenarios can be tested, but it is often avoided because of the overwhelming time it takes to create and maintain said data. The data can also be “created” automatically by retrieving data from a production server. This method drastically reduces developer labour. However, there are issues when requesting data from a production server:

The challenge now becomes determining a solution that generates mock data for UI tests without the overexertion of developers and the costs of using production servers. Enter Raven. Raven is Loblaw Digital’s in-house Android testing library that enables developers to mock production data, store it in a shareable cloud database, and use that mock data for their UI tests. This means developers have an automated solution for creating mock data and testing their apps in a non-volatile environment.

Raven’s simplified workflow
Raven’s Workflow

The Internet holds an array of information hosted on servers. Apps usually need data from a server to display personalized information to its users. For example, to obtain data on a certain food item, a grocery app requests data on said food from the respective server. The app just made a network request. Typically, the request and the server communicate through REST API, which defines what the request wants the server to do (GET data on a certain food item, POST this data, etc.).

If the request requests to POST data to a server, RetroFit turns the data we want to POST into a JSON and defines the location of the server, then OkHttp “goes” to the server and gives the data to the server to store (the act of OkHttp going to the server is called a request).

The process of OkHttp transferring data to/from the server is when Raven creates the mock data. When a GET request is made, Raven intercepts OkHttp and copies the data OkHttp receives from the server and stores it in a cloud database. Raven does the same when a POST request is made, except it copies and stores when OkHttp is going to the server with the data, as opposed to returning from the server.

Raven intercepts every REST API call, but what do we mean by intercept? Interceptors are a mechanism that performs an action whenever data is going to/coming from the server. How does an interceptor know when a request or response is made? We connect the interceptor to the OkHttp instance and act according to the REST API call (GET/POST).

Raven stores the mock data into a cloud database because cloud databases are scalable and provide ease of access.

Firestore and Raven Example

First, Raven’s Firestore interceptor mocks the data being held by OkHttp. Once the mock is created, Raven prepares to store the mock data to Firestore.

Raven will have its own collection titled “raven”. Then Raven creates a unique document for every REST API call made and stores the respective mock data as the document’s data. The IDs of these documents will be the production endpoint URL. This will allow the mock data to be stored/retrieved in an organized manner.

After the document has been created, Raven then converts the mock data into a hash map data structure so that the fields and their respective data can be stored.

Realtime stores data as one large JSON object. This is favourable because it makes it easy to store and parse data.

Realtime works well with network libraries such as RetroFit, however, in operations like POST there are difficulties. Realtime creates a new JSON object with a unique ID every time, making it difficult to override already existing JSON objects.

Raven and Realtime Database Example

For Raven’s Realtime Database interceptor to store the mock data into Realtime, the first thing Raven does is define where Realtime is. The interceptor does this by taking the entire URL from RetroFit (base and endpoint URL) and changes the base URL to match the URL of the instance of Realtime Database for Raven. The interceptor will keep the endpoint the same to allow for straightforward storage and retrieval.

Raven will take the data that is being sent to/from the production server and convert into a JSON type object so that it can be easily stored into Realtime. However, Raven cannot POST the data due to the fact the Realtime creates a new ID for every POST operation.

To bypass this, Raven creates a new request to Realtime. This new request contains all the information of the original request, except changes the POST operation to a PUT operation. The POST operation is used when developers want to add data, while PUT is used when they want to update data.

In a GET operation, Raven copies the response from Firebase. However, the response is a collection of documents rather than the expected REST API response. This means information such as the status code and headers will not be present in the mock data thus disabling us from testing different scenarios for our UI tests. We need the data to return as a REST API response, not a collection of objects. To solve this, Raven relies on creating a mock web server that mimics the behaviour of an actual server.

MockWebServer creates a mock server. Raven redirects the response from the production server to the mock server by attaching a base URL interceptor to the OkHttp instance. The base URL interceptor changes the base URL RetroFit gives to OkHttp to match the location of the mock web server, which, in Raven’s case, is the localhost. This is important because now we can store the collection of objects as a REST API response. In a POST operation, MockWebServer works the same, except the request is intercepted when OkHttp is going to the production server as opposed to coming from the server.

The data stored in Realtime is already stored as a REST API response, so there are no changes needed to be made to the response itself, the only issue is informing OkHttp where to get the response.

At first, OkHttp would go to the production server to get the data required by the UI tests. However, Raven intercepts this request and tells OkHttp to go to Realtime instead. This is once again done through the base URL interceptor. The base URL interceptor changes the base URL RetroFit gives to OkHttp to the base URL of Realtime. The endpoint URL stays the same because the data stored in the cloud database is stored the exact same way as it was in the production server. This means, after only changing the base URL, OkHttp requests the data from the Realtime rather than production, but provides the same response.

Raven is also able to use data stored in the repo for its mock data. For example, if a JSON were to contain the data a UI test could use, developers could specify to use the locally stored mocked data as opposed to Cloud Firestore or Realtime Database. Reading from local storage is very similar to reading from Firestore. To mimic an API response, Raven relies on MockWebServer’s ability to create a local host server and sets the local mock data as the response from local host, rather than the data from Firestore, thus mimicking a production endpoint.

Recording locally is not possible due to the restrictions Android has when it comes to creating files and directories programmatically.

Developers are benefitting from the computerized way in which Raven generates and utilizes mock data. It instantly creates mock data at real time, removes the troubles of hitting production endpoints, and stores it in a cloud database available to both the Android and iOS teams. The solution Raven provides increases the test culture here at Loblaw Digital, and plays a key part ensuring the quality of our apps.

Raven is still at the beginning of its development at Loblaw Digital and is only expected to grow in the coming years.

Add a comment

Related posts:

Amazon S3

Amazon S3 is easy-to-use object storage with a simple web service interface that you can use to store and retrieve any amount of data from anywhere on the web. Amazon S3 also allows you to pay only…

10 Important key points to describe Why Graphic Design is Important?

1. Graphic Design helps businesses create a unified visual identity and build their brand recognition. 3. Graphic Design allows businesses to stand out from the competition by creating unique visuals…

How to answer a Product Improvement question in a Product Manager job interview

Interviewers like to ask product improvement interview questions as a way to evaluate your ability to: To start off in the right direction, you need to explain your understanding of the product —…