mitmproxy provides tools for observing and modifying network exchanges. It is particularly useful when manual inspection is insufficient: repeatedly returning a chosen response, adding a diagnostic header, or checking several network conditions. Python rules can be reviewed alongside the test scenario.
Use your own application and an agreed test environment. A proxy affects routing and TLS, so keep experiments narrowly scoped and include a control run. A response-substitution script checks client reactions to a chosen response; it does not establish real server behavior under arbitrary failures.
Interfaces and operating mode
mitmproxy provides an interactive interface, mitmweb a web interface, and mitmdump command-line execution. They share flow and addon mechanisms. Interface choice affects observation convenience, while correct traffic routing remains essential.
Start with an ordinary explicit proxy and one test client. More complex modes require separate routing and permission setup. Starting the tool does not make traffic appear if the application ignores the system proxy. Confirm a control request first.
Reading a flow
HTTPFlow connects a request and response with connection context. QA inspects method, host, path, headers, body, status, and timing. Distinguish background refresh and analytics from user operations through data and sequence.
Compare successful and failing attempts. If the client changes identifiers or retries after a timeout, substituting one response may affect only part of the chain. Record every significant attempt rather than describing several different operations as one request.
HTTPS, CA, and pinning
To decrypt HTTPS, the client must trust the CA belonging to that mitmproxy installation. The root certificate and private key are different files; never distribute the key with client instructions. Individual application libraries may not use system trust.
Pinning may reject proxy certificates even with a trusted CA. Use an agreed debug configuration for your own application and test the protected build separately. Do not disable certificate validation in production code for convenient diagnosis. Remove unnecessary trust and proxy settings afterward according to team procedure.
A minimal addon
The example below returns 503 only for GET /api/catalog on your own test domain. Save it as catalog_fault.py. It creates a response in the request hook, so matching requests never reach the server. This distinction matters when interpreting results.
import json
from mitmproxy import http
def request(flow: http.HTTPFlow) -> None:
req = flow.request
if (
req.pretty_host == "qa.example.test"
and req.method == "GET"
and req.path.split("?", 1)[0] == "/api/catalog"
):
payload = {"code": "CATALOG_UNAVAILABLE"}
flow.response = http.Response.make(
503,
json.dumps(payload).encode("utf-8"),
{"Content-Type": "application/json"},
)mitmdump --listen-host 127.0.0.1 --listen-port 8080 -s catalog_fault.pyThe command listens only on the local computer; configure a client on that computer for 127.0.0.1:8080. A phone cannot use that address to reach another computer. Remote clients require a separately agreed network route, and HTTPS also requires the trust setup described above.
Verifying the substitution
Before testing the UI, verify the addon's expected status, header, and body. Then issue a neighboring request that should not match; it must follow the normal route. This checks both the intended effect and the absence of unintended effects.
In this example, query parameters do not affect path matching, so every catalog variant receives the error. If only one filter should be affected, refine the condition using parsed parameters. Avoid broad URL substring searches when targeting a specific endpoint; accidental matches hinder investigation.
A practical client scenario
The catalog must retain filters during a temporary failure. Prepare a test build and a populated catalog. First run without the addon and record normal state; then enable substitution and repeat the same actions.
- 1.Open the catalog with a category selected. Expect a clear failure message, completed loading state, and preserved selection.
- 2.Retry while substitution remains active. Expect bounded, understandable behavior without an uncontrolled request loop.
- 3.Disable the addon and reload. Expect success and the list restored with its original filters.
- 4.Check a neighboring section. It should work normally; a narrow rule must not disrupt profiles or authentication.
Compare button presses with network attempts and client state. This timeline can reveal duplicate handlers or retries that never stop.
Responses after server operations
The response hook runs after receiving a server response and has different semantics. Replacing successful order confirmation with an error may happen after the order was saved. This usefully tests an uncertain outcome but requires separate final-state verification.
Distinguish pre-send failure, delay, connection interruption, and post-execution response substitution. They may look alike on screen but test different guarantees. Side-effecting operations need unique test data, idempotency rules, and cleanup plans.
Repeatability and artifacts
Store addons with their assumptions: build, domain, error contract, and intended effect. A changed JSON contract can invalidate an old substitution, making the test reveal only an artificial response mismatch. A negative control helps detect this.
Saved flows may contain tokens, cookies, and personal data. Capture only necessary traffic and sanitize artifacts before sharing. Scripts can contain secrets too; do not embed permanent credentials for convenience.
Common mistakes and tool limitations
Common mistakes include leaving addons enabled, choosing the wrong hook, treating a mock as proof of server failure, and blocking the event loop with heavy synchronous work. Proxies can also alter timing, so their measurements do not automatically apply to direct connections.
A good QA result is a small, clear rule with a confirmed scope and verified client response. This is easier to reproduce manually and automate than an undocumented random network failure.