Charles Proxy

How QA engineers use Charles Proxy to analyze traffic, replace responses, and debug web and mobile scenarios.

Updated:

Contents

Charles Proxy lets you inspect HTTP exchanges between an application and server, and make controlled changes to network conditions or responses. For QA, it connects an onscreen action to a specific request: what data was sent, what the server returned, and how the client handled it. It is particularly useful for interface states that are difficult to trigger.

Start with your own test application and a limited set of domains. The proxy becomes part of the request path and can itself affect behavior. Reports should distinguish product issues from effects of the configured experiment. Supplement proxy observations with a direct control run without it.

How routing works

The client sends traffic through Charles, which contacts the server. On a computer, the proxy can be configured system-wide or for a particular application. On a phone, set the computer's address and port in the active network's settings if the application supports that route.

Check computer reachability, Charles access rules, and the selected network interface. If requests are missing, first establish whether the client uses the proxy. Do not immediately change certificates: routing problems, VPNs, caching, and a different network stack can produce similar symptoms.

Requirements for HTTPS

To read HTTPS content, the client must trust the Charles test root certificate, and the relevant domain must be enabled in SSL Proxying. Seeing CONNECT or a hostname without the request body does not mean decryption works.

System trust does not guarantee trust in every application. Pinning or a separate certificate store may block connections. For your own application, use an agreed debug build and trust configuration. Disabling certificate validation in the production product does not solve the testing task; test the protected build separately.

Reading a session

Clear old records and perform one action. Find the request by domain, method, and path. Compare the query, headers, body, status, response, and timing. Confirm that you selected the operation's request rather than background analytics or a preflight request.

For example, saving a profile may send two requests, return 200, yet contain the old data. These suggest different investigations: duplicate submission, the server contract, or client state updates. A screenshot of the request list rarely communicates that distinction without context.

Map Local for interface states

Map Local returns the contents of a local file in place of a matching URL's response. For your own catalog, prepare JSON containing an empty items array and map the file to the exact /api/catalog path on the test domain. The request should produce the intended empty state without crashing the client.

Check Content-Type and the body actually received; incompatible headers can create a different defect. Consider URL matching rules: Map Local has specific query-handling behavior. If the same path needs different variants based on parameters, verify which rule is selected and use a suitable tool instead of assuming an exact match.

Rewrite and breakpoints

Rewrite is useful for repeatable changes to a header or part of a response. A breakpoint pauses before sending a request or delivering a response so you can edit selected data manually. Choose the narrowest possible condition to avoid affecting login, token refresh, and unrelated endpoints.

Changing a response does not cancel a server operation that has already run. If the server created an order but the proxy replaced the confirmation with an error, the order may still exist. Check the final state and distinguish “the server did not perform the operation” from “the client did not receive confirmation.”

Practical example: a save error

In your test application, the profile form must preserve entered data after a network error and offer a retry. Prepare a separate account, an initial name, and a new test value. First make a successful control request and save a sanitized contract example.

  1. 1.Restrict the rule to the exact test domain, method, and save path. It should not affect profile loading or authorization.
  2. 2.Replace the response with an agreed 503 error and a contract-compatible body. Expect a clear message, the end of the loading state, and preservation of the entered value.
  3. 3.Read the actual profile independently. If the request reached the server, the new name may have been saved despite the onscreen error.
  4. 4.Disable the rule, repeat the action, and refresh the screen. Expect consistent client and server state without repeated side effects.

This experiment tests handling of the selected response. It does not model every network failure or prove that the real server returns exactly that body under overload.

Latency and bandwidth limits

Reducing bandwidth helps investigate resource loading and behavior during slow exchanges. Latency, bandwidth, and connection loss are separate factors. A single throttling mode cannot reproduce all mobile network conditions, interface switching, or transport behavior.

Record the parameters and identify which traffic they affect. Check whether users can cancel the operation, whether progress is clear, and whether the application recovers after the limit is removed. An interface that remains blocked after a successful response is a more specific finding than “slow.”

Why results can be misleading

A response may come from the browser cache or a service worker and not appear where expected in the session. The application may retry automatically, and a global rule may affect the retry too. Check attempt counts and their sequence.

The proxy affects TLS and network routing, limiting timing measurements made through it. Conclusions about server performance require an appropriate experiment and control measurement. Charles is useful for diagnosis and response simulation; it does not by itself establish server capacity.

Artifacts, cleanup, and conclusions

In the bug report, include the build, device, route, rule, original action, and expected behavior. Attach the relevant request and response after removing tokens, cookies, and personal data. Before sharing a session file, inspect all its contents, including background traffic.

After testing, disable rules, restore proxy settings, and remove unnecessary test trust according to team procedure. Common mistakes include leaving response replacement active, treating a response error as cancellation of the operation, and checking only the visual message. The useful outcome from Charles is a precise explanation of how the application responds to known network conditions.

Further reading