Once upon a time I was told I’d be working on a new and exciting mobile app, only not as a developer…but as a tester.
Although this was my first time testing mobile products, it meant I could play around with different devices, which got me very excited! However, a few thoughts came to mind:
- How can I verify the APP sends the correct data to the backend?
- How can I check whether the backend response the expected information to the APP?
- How to simulate 400 bad request error scenarios on the APP?
- How to simulate sending invalid data to the backend?
- How to automate testing for all of the above?
After doing some research and asking my colleagues for their insights, I explored the idea of using various tools such as Charles, Fiddler and Postman. Then I discovered the answer to my questions…mitmproxy.
What is mitmproxy?
mitmproxy is a free and open source interactive HTTPS proxy, which has the following features:
- Web page GUI support
- Terminal GUI support
- Python scripting
- Record and replay
How does it work?
mitmproxy is really easy to install on MacOS. You only need to execute one command in command line.
brew install mitmproxy
To launch the application, execute one command and it will pop up a web page in your browser: http://127.0.0.1:8081/
(You can use mitmproxy / mitmweb / mitmdump — I’ll explain later)
mitmweb
Good job. Now you need to connect your mobile device to the mitmproxy, and allow it to trap the HTTP traffic.
https://docs.mitmproxy.org/stable/overview-getting-started/
- Set-up the proxy on the network on your device (the proxy IP is the IP where you are running the mitmproxy.
- Visit http://mitm.it from the browser on your mobile device.
- Install the proxy based on the type of your mobile device.
OK, let’s go back to the open page — http://127.0.0.1:8081/ — and launch the app you are testing. Did you see traffic between the app and the backend? Bingo!
There are three applications with which mitmproxy can provide scenarios for:
- mitmproxy — If you like terminal console, and would like to use it in server only mode.
- mitmweb — If you prefer the web page based console.
- mitmdump -If you’d like to record / replay the HTTP traffic.
Most features are available with the three options too. For more information, visit this doc — https://docs.mitmproxy.org/archive/v4/concepts-options/
What did the testing involve?
Let’s start testing. First of all, I had to find out whether our app communicated with the backend. This meant opening the testing app on mobile and using the Filter field on mitmproxy web console.
The HTTP request and response was expected. I could then view all the details in the right panel.
When using the mitmproxy app, I can view the same data but with a different console GUI.
The next step was to simulate some fake data in the request API. After working on the contribution API, I changed the completedCalculations in the request body to 100 and observed what happened.
I put the request URL in the Intercept field and used the app to trigger the API request. I could then see the request in mitmproxy with different colors and a ‘pause’ icon.
Clicking the tick button on the right panel took me into editor mode, where I could change the completedCalculations to 100 in the payload.
I clicked the Resume button in the Flow tab, which paused it again because it is interrupted in response of the API request. Time to click Resume again.
Success! It passed the 100 as completedCalculation to the backend, which I could verify.
It’s possible to modify the response data in the same way too.
That’s how we can use mitmproxy to debug our mobile app.
Finding and reporting a bug
While using mitmproxy, I found and reported a bug. Before running diagnostics, our developers wanted details of the HTTP requests.
But how could I do this? Should I copy and paste all request / response data to the bug management system or a file and share with the developer? Or is there a better way?
I ran the below command in Terminal, which started the recording mode.
mitmdump -w outfile
Next I opened the app and reproduced the issue of the bug. Once the steps were complete, all the traffic data would be saved into “outfile”.
I could then share this file to the development team, and they could simply run the below command to replay it.
mitmdump -nC outfile
For more information, please refer to https://docs.mitmproxy.org/stable/overview-features/#client-side-replay
What else can I do with mitmproxy?
My experience with mitmproxy got me thinking…
- How can I simulate more complicated scenarios and datas?
- How could I use mitmproxy in our automation test framework?
The answers to these questions require a Python script. If you’re not familiar with Python, you might need to find out whether there’s an add-on for mmitmproxy which can work with other languages.
I wrote the following Python script, tried to catch a request, then rewrote the response.
To launch mitmproxy with the script, you can use any command below:
mitmproxy -s proxy.pymitmweb -s proxy.pymitmdump -s proxy.py
Open the app, continue the testing steps, and you will see the response has been rewrote.
Our automation test framework is based on NodeJS (Javascript), so to integrate mitmproxy, we must call the script in a sub process. Discover more here — https://docs.mitmproxy.org/stable/addons-scripting/
Final thoughts
Bear in mind that this article only covers the most basic functions of mitmproxy. There are several advanced features I didn’t talk about.
When we talk about free and open source tools, it’s natural to assume they’re hard to use, unstable and don’t come with enough documentation.
But did I feel this way about mitmproxy? Not at all.
It’s easy to get going with, reliable 99% of the time and really flexible. Also, it’s free!
I hope you’ve enjoyed this introduction to mitmproxy. It would be great to hear your thoughts if you’ve also given it a try.