Using Charles
Last modified on Fri 22 Jul 2022

People always say "code and then test," I prefer “test and then code."

Charles is an HTTP proxy that helps you to inspect HTTP/S traffic. For the purposes of this tutorial, we will focus on Charles as a man-in-the-middle between the app you are testing on a mobile device and the Internet.

Charles setup

iOS setup

To be able to use Charles on iOS you need to do the following:

  1. Open Settings on your iOS device
  2. Tap on Wi-Fi
  3. Select the network to which your iOS device and your laptop are currently connected
  4. Tap on "Configure proxy"
  5. Tap on "Server" and enter your laptop's local IP address (find it in macOS' Network Preferences)
  6. Tap on port and enter "8888"

Android setup

It differs from device to device, but it usually goes something like this:

  1. Go to “Settings”
  2. Go to “Wi-Fi”
  3. Long tap on the Wi-Fi network to which the device is currently connected
  4. Tap on “Modify network”
  5. Tap on “Show advanced options”
  6. Select "Manual" in the “Proxy” menu
  7. Under “Proxy hostname” enter your laptop's local IP address (find it in macOS' Network Preferences) and under "Proxy port" enter 8888

After several seconds, you should get a prompt in Charles asking you to confirm traffic coming from your device.

If that does not happen, try restarting Charles. Now you will see all the traffic that your device is sending out and receiving, but it will be encrypted if done via a secure protocol (HTTPS).

SSL proxying setup

To see HTTPS traffic in plaintext, you will have to set up SSL proxying:

Now you should be able to "Enable SSL proxying" on an endpoint you are interested in and see unencrypted traffic in both directions.

Note: the above will not work if there is a pinned certificate in the app.

Adjust traffic

How to use breakpoints

Breakpoints enable you to stop requests/responses "mid-air" (in Charles) and change them before forwarding them back to the API or to the mobile app. By doing so, you effectively take full control of all the networking. :)

To set up a breakpoint, right-click on an endpoint and select "Breakpoints":

Select breakpoints

After that, execute some requests in the mobile app towards that endpoint and wait for Charles to intercept them.

Now you will be able to change the request before executing it if you wish to do so. You will also be able to change the response before forwarding it to the phone.

Debug breakpoints

If you want to rewrite requests and responses automatically, you can use Charles' Rewrite tool.

Exporting traffic to a HAR file

You can multi-select several requests and export them as HAR files, just make sure to select the HTTP Archive (.har) format.

Now you will have a file that is basically a snapshot of all the requests you’ve made and all the responses received.

Why would you that? One possible use case is to convert that HAR file to a k6 script and get a load test for free. :)

Repeating requests

Let's say you have to create 100 articles in the mobile app you are testing to satisfy the preconditions for a certain test case. Let's also assume you don't have access to API docs or a Postman collection that could come in handy.

These are some of your options:

Charles can help you achieve the 3rd option. Just isolate the request you want to repeat, right-click on it, and select "Repeat Advanced".

Once you enter the amount of iterations, click on "Ok" and watch Charles do his magic.

repeat.png

If you want even more flexibility, you can right-click on the request, select "Copy cURL request" and get a nice cURL command that's good to go:

curl \
'https://api.foo/api/v1/resource' \
-H 'accept: application/vnd.api+json' \
-H 'authorization: mytoken' \
-H 'content-type: application/vnd.api+json' \
-H 'accept-language: en-GB' \
--data-raw '{"data": "mydata"}' \
--compressed

Now just add repeat 99 in front of your cURL command, execute it in your terminal of choice, and you're off to the races. :)

The nice thing with cURL commands is that you can easily share them with the rest of the team.