How to debug mobile app requests and test their APIs

Even though app usage on desktop devices has maintained a steady leader position, over the past few years, mobile devices have been gradually gaining ground. It is safe to assume that this trend will continue on its trajectory.

For this reason, the IT industry invests more and more in this sector. New technologies and innovative apps are available each day. Usage for these apps is also growing exponentially and for this reason, the testing effort must improve and keep up as well.

The purpose for this article is to cover a few key points like:

  • Explore 2 really useful tools like Fiddler and JMeter

So, let’s get into it!

Before starting the actual practice, we need to understand a few basic concepts (like proxy). Also, understanding what each application we are going to use does is an important factor, and see if there are any requirements for that app to work on your system.

Also, for the practical part, we will need a mobile device (Android or iOS) and a PC/ Laptop/ Mac.

I. What we need

Fiddler

Fiddler is a powerful web debugging tool usable for multiple operating systems (Windows and Mac OS) and devices (PC and Mac).

In the current context it will only be used for web debugging but it can also be used for recording http/https traffic, for performance testing, for web session manipulation and security testing.

Apache JMeter

JMeter is an open source testing software created by the Apache Software Foundation in 1998. The application is 100% Java based (runnable on most major operating systems) and it is mainly used for load testing, analysing and measuring the performance of web services. It is also used for stress testing and to determine the maximum load capacity of a server.

In the current context, we will not be using it for performance testing, but for creating a script which is designed to test certain functions of an API.

Java Software

Java is a programming language and a computing platform. Many applications and website will not work properly if we don’t have Java installed. This is the case for JMeter as well, we need java in order to be able to run JMeter.

Up until JMeter 4 which was released on 10.02.2018, Java 8 was required for the app to run but starting version 4, JMeter is compatible with Java 9.

The Mono framework (for Mac users)

In order to be able to run Fiddler Beta on MacOS, Mono is required.

Fiddler was initially designed only for Windows platforms, and that’s where Mono comes in.

Mono is a open source project designed with the purpose of running Microsoft .NET applications cross platform. Since this software platform can run on most software systems like Android, Linux and MacOS, we will need it in order to run Fiddler on Mac devices.

Understanding the concept of Proxy

A proxy server is an intermediary for requests which travel from client to server and vice-versa.

A proxy can exist on the same machine as the client or server. It can also exist on a separate machine. This is the case for the setup we are going to use in the current context where we will have a client (mobile phone with an application we want to debug), a proxy server (our PC or Mac) and a Server (which communicates with the client).

Advantages of a proxy include the fact that proxy server caches can serve all users of a website which should improve response times for that user. Also, proxies are used to protect privacy by granting anonymity on the WWW or just for bypassing restrictions to some sites which only offer content to users matching a particular IP (Youtube is a good example which restricts access to some videos in certain countries and that can easily be bypassed).

There are 2 types of proxies — forward proxies or gateways and reverse proxies. In the current context we will be using a tunnelling proxy or a gateway which basically gives us visibility to the request exchange between a mobile phone with a certain app using the internet and the server it communicates with.

Having gone through this theoretical part we can now can get to the practical part.

II. What we should do

1. Install Java

  • You probably already have java installed, and if you don’t, you need to do just that (it’s a simple process on both Mac and Windows).

“java version “1.8.0_131”

Java(TM) SE Runtime Environment (build 1.8.0_131-b11)

Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode”

2. Install Mono (Mac users)

In case you are working on a Mac, you will need to install Mono before trying to run Fiddler.

  • First you need to download and install Mono. If it’s already installed on your system, you should update it.

3. Install Fiddler

  • The first thing you need to do is download Fiddler from here.
  • On Windows, you need to click ‘Trust Root Certificate’ then accept to trust the fiddler certificate.
  • One last step for both operating systems would be to import the exported Fiddler certificate into Mozilla’s trusted certificate section. I suggest using Mozilla if you want to do HTTPS web debugging since it’s really easy to import the certificate and changing the proxy to match whatever you set in Fiddler. To do this, simply open the Firefox ‘Certificate Manager’, navigate to the ‘Authorities’ section and import the Fiddler certificate. You should see this modal popping up:
  • Tick all 3 checkboxes and press ‘OK’. After this step you should no longer see certificate errors popping up in you Firefox browser when trying to decrypt HTTPS requests.

4. Install JMeter

  • The installation steps for JMeter are really simple, you simply need to download the JMeter zip from here, unzip it and you’re basically set.

5. Setup the Fiddler proxy (phone and PC/Mac side)

There a few extra steps we need to undergo here.

  • In Fiddler, navigate to the ‘Connections’ section (“Tools -> Options…”)

If you don’t see this page, then the port is not open and you need to retake the previous steps carefully.

  • Access the same URL on the mobile phone you want to capture requests from
  • The installation process is straight forward for Apple devices (Allow -> Install -> Install -> Done).
  • Set a manual proxy: This is the final step before we can actually start recording traffic going from and coming into our phones. Navigate to the ‘Wifi’ section, select your current wifi network and configure a manual proxy. The server field should be the IP address of your proxy server and the port should be the one which you set in Fiddler during the previous steps.

Important!

It is important to note that now that you have a proxy set, the minute you close Fiddler, the port is also closed. This means that the your internet connection won’t work on your phone unless you reopen the port or unless you remove the manual proxy setting and change it back to automatic.

Also, if you choose to do so, you can remove the installed Fiddler certificate on both your iPhone or Android device.

6. Inspect requests and create JMeter script

After we performed all these steps, we can start debugging the requests from the mobile app we are interested in.

My suggestion would be to set a filter on Fiddler to only display requests from a certain domain. If we do this, we avoid cluttering the workspace and getting overwhelmed by too many displayed requests (since Fiddler will capture all requests ingoing from our phone).

  • To set a filter, navigate to the ‘Filters’ tab, check the ‘Use filters’ option and check the ‘Show only if URL contains’ where we can set the domain name or part of the domain. Below you can see the required settings:

An application could use multiple APIs, it can use an API from Google or Facebook. This means that all calls ingoing to Google or Facebook will also be displayed in our Fiddler interface. If we want to exclude certain requests from the interface, check the ‘Hide if URL contains’ box and add certain domains to your ignore list, which means that calls from that domain won’t be recorded.

  • Whenever you perform a certain action in the app you are testing, one or multiple requests will be launched and Fiddler will capture all these requests

All the information about a request and its response can be found here. The screenshot below depicts the steps mentioned above and elements from the Fiddler UI:

We can see in the example request, that the request body is in json format and the response is also a json. This means that the application uses a REST API. If the screenshot above is not visible, try to view it from here.

7. Create a script

Now that we know how each request looks like, we can move to simulating these requests into JMeter. Since this is not a JMeter basic tutorial, we will not undergo the basics of this tool and jump directly to the practical part.

We will on the other hand, go over a sample script and briefly mention all elements included in it. The sample script which is a JMeter .jmx file can be found here.

All the data present in the dummy script is fictive and I changed everything from the original script which might be sensitive information. Before moving to the next step, make sure you open the .jmx with JMeter and see all elements of the script.

Important! The script contains some elements which don’t come by default with JMeter, and you need to install them. To do this, simply download the JMeter plugin manager from here and move the .jar file to JMeters folder in /lib/ext. If you are using JMeter 4, the next time you launch the app and try to open the .jmx, the missing elements will automatically be installed.

For the sake of learning, let’s imagine we are building an API functional test for a mobile booking app. That’s what the above script is for.

The script has 2 main sections: the configuration section and the functional test section.

The configuration section:

This part contains all the elements we need to configure in order to be able to run the script efficiently.

  • The first 2 elements, the MySQL Variables and Mobile App Variables are used to define all the variables we need throughout the script. It’s usually a good idea to do this here, so that our tests are maintained more easily and if something changes, we don’t have to look all over the place to make a change.

The test section:

This section contains the requests we are simulating and all the checks we need to make in order to decide if a test is passed or failed.

  • The first 2 elements are MySQL queries.

One of them retrieves the id of the test user (SELECT id FROM ${dbName}.users where phone = “${mobPhone}”;) which we need for a future assertion (the ‘${}’ syntax is used to call an existing JMeter variable e.g if mobPhone= 12345 then ${mobPhone} will return 12345). The user id is stored in the ‘dbUserID_1’ variable.

The second SQL query deletes an active reservation of the user if he has one (DELETE FROM ${dbName}.some_table where user_id = ${dbUserID_1} and active = 1;).

A more elegant approach would be to include these 2 into a ‘Data preparation’ controller along with any other elements similar to them which retrieve or generate data needed for our test.

  • Then there is a series of POST and GET requests. Since the application under test uses a REST API, the requests will send and receive json files.

The first request is a typical login request where we send the phone number and password parameters in the request body. The request contains 4 child elements: one json extractor where we extract the Token variable using the ‘data.accessToken’ expression and store it in the ‘accessToken’ variable. The other 3 elements are json assertions. These assertions are necessary to check if the requests return the expected data.

The next request updates the map with all areas of interest according to the user position. For this, we send the ‘accessToken’ previously extracted with the request and the user position (lat and long). The coordinates are generally determined by our mobile phone, but since we run the test on a pc we need to hardcode those 2 values.

The 3rd request creates a new reservation to a close-by location. The ‘Delete reservation’ query from the beginning is necessary because if the user already has a reservation which didn’t expire, he cannot create another one. This means that the request would have responded with 405 (not allowed) even if the reserve function is working just fine.

The last request is a simple GET request which retrieves the profile image of a user.

  • The last 2 elements are used strictly for debugging purposes and to see how the requests we generated look like. If we compare the requests and responses displayed in the ‘View results tree’ element, they should be same as the requests we previously inspected in Fiddler.

Of course, this is a basic scenario which only contains a few calls. Some scenarios can get really complex and if we don’t organize them well enough we can get lost pretty easy. A really cool approach a coworker showed me recently is to group all similar elements (SQL queries, POST request, GET requests etc) in test fragments outside of the Thread group element. Each individual request must have a simple controller as a parent. Then in the Thread group section you simply define flows which consist of module controllers where you can simply call for requests defined above. This approach is efficient and we avoid having duplicate code especially if there are multiple flows which have a certain common part but this will be elaborated further in a future article.

Finally, we should explore the possible advantages for doing the ideas presented in the previous section.

III. What we have to gain from this approach

There are a few possible advantages to this approach we should take into consideration:

  • We gain better understanding as testers of how the client — server interaction works

Hopefully the information presented above will improve the testing effort for those interested in exploring this approach. Even if you are not designing API tests, it’s useful to explore the generated requests from an app while doing manual testing just to gain a deeper understanding on how everything looks behind the scenes. Who knows, it might help us catch some nasty bugs we would have never known about. Happy bug hunting!

--

--

Software tester passionate about coffee and reading ☕📚

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store