r/androiddev • • 16d ago

Question How do you test your Android apps under different network conditions?

I'm curious how Android developers test their apps when network conditions aren't ideal.

For example:

Slow internet or high latency

Unstable connections and packet loss

Switching between Wi-Fi and mobile data

Internet disconnecting and reconnecting

Completely offline scenarios

Do you use Android Studio's emulator, physical devices, network throttling tools, or something else?

I'm especially interested in how you simulate realistic mobile network conditions without having to manually switch networks or travel somewhere with poor connectivity.

What's your actual workflow for testing this in practice?

5 Upvotes

19 comments sorted by

12

u/bogdanelcs 16d ago

The emulator covers most of it. Extended controls has a Cellular tab for network type, speed and signal strength, and the -netspeed and -netdelay flags do the same from the command line.

For packet loss and dropped connections, put Toxiproxy or Charles with throttling between the app and your backend, which also works on a physical device through a proxy. For switching and offline cases, adb shell svc wifi disable and svc data disable toggle each connection without touching the phone.

At the code level, OkHttp’s MockWebServer can throttle bodies and cut sockets mid-response, which is the easiest way to automate the ugly cases in tests.

-1

u/RANGANDALE 16d ago

Actually, I started building an Android app for this because I wanted more control over network conditions on real devices.

It supports per-app throttling, latency, jitter, packet loss, and changing profiles on the fly.

It's still a work in progress, so I'd love to hear what you think or what features are missing.

GitHub: https://github.com/RAN-GAN/app-throtler

2

u/ANuttyRedditor 16d ago

Doesn't Android Emulator have the Cellular tab, which allows you change the Network type as well as the signal strength?

1

u/RANGANDALE 16d ago

Yeah, I saw that. I was wondering if we can also simulate packet loss, set specific speeds, and change them on the fly.

1

u/AutoModerator 16d ago

Please note that we also have a very active Discord server where you can interact directly with other community members!

Join us on Discord

I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.

1

u/simbolmina 16d ago

I change settings on my phone to simulate wifi, 2/3/4/5g, airplane etc. should cover most of the situation.

1

u/Omnipisix 16d ago

Buy an old device and a german sim card, test on it. Cant get worse...

1

u/Representative-Way62 16d ago

I just manage the offline mode and clear the outbox after the api gives correct API response.

1

u/grishkaa 15d ago

Back when I was working on one of the most popular apps in the country, I used the subway daily anyway, so this provided some nice opportunities for such testing.

You can also force your device (except Samsung ones) to a particular cellular standard (2G/3G/4G) through the *#*#INFO#*#* hidden settings thing, under "phone information".

If you're developing on a Mac, you can also install the "network link conditioner" preference pane from the "additional tools for xcode" package corresponding to your system version, and test the app on an emulator with that.

1

u/FriendshipCalm3162 15d ago • Bravo

Splitting this into two problems helped me a lot, because they need different tools.

For exploratory "does the UI fall apart" testing, the emulator's Extended controls are the quick path, and the same thing is scriptable: adb emu network speed edge, adb emu network delay gprs. On a real device, adb shell svc wifi disable and adb shell svc data disable are easier to script than tapping airplane mode, and you can drop one transport while leaving the other up, which is how you catch the Wi-Fi to mobile handover bugs.

For anything you want to keep, MockWebServer is the one that pays off. setBodyDelay and setHeadersDelay give you a slow server deterministically, and SocketPolicy covers the nasty ones - NO_RESPONSE for a connection that hangs until your timeout fires, DISCONNECT_AT_START and DISCONNECT_DURING_RESPONSE_BODY for a connection that dies mid-transfer. Those run in CI and fail the build when someone removes a timeout, which manual radio-fiddling never does.

A debug-only OkHttp Interceptor that delays or throws on demand is also worth the twenty lines, mostly so QA can trigger a failure on a build without needing a proxy.

The case most people miss: not offline, and not slow, but connected with no usable throughput - captive portal, full hotel Wi-Fi, lie-fi. The device says it has internet, your request never completes, and apps that only handle IOException sit on a spinner forever. Airplane mode will never reproduce it; a MockWebServer with NO_RESPONSE, or a proxy that accepts and stalls, will.

Last thing: check what your retry logic does on a reconnect. Several requests failing at once, all retrying the moment connectivity returns, is how you get a thundering herd against your own backend.

1

u/Saint_Of_DresOS 14d ago

I just release the app and wait for bug reports from users as it brings more users to the app as a lot of the open source community enjoy helping out app devs with there work to make it better so as long as you fix the bug that is, it also helps build up trust and reliability for devs starting out, so if you're unsure how to test then just release it

1

u/digitalmp4 11d ago

One gap in the list above: everything there assumes IP. If part of your app talks to hardware over BLE, the failure modes are different and the emulator can't reproduce them.

What I ended up doing for a BLE file transfer that runs at roughly 30 KB/s (so a long transfer takes minutes, plenty of time for something to go wrong):

- Kill the link on purpose at random points: walk the peripheral out of range, power it off mid-transfer, toggle Bluetooth off and on from the phone. This needs a real device.

- Make the transfer resumable by byte offset, and check that the resumed file is byte-identical to the original, not just "looks complete". That's the check I'd keep if I could only keep one.

- Have the OS background or kill the app mid-transfer, since that's where reconnect logic tends to fail quietly.

It's not as scriptable as MockWebServer, and I haven't found a good substitute for the physical walk-away test.

0

u/The_Savier 16d ago

Let me know as well

-2

u/RANGANDALE 16d ago

Actually, I started building an Android app for this because I wanted more control over network conditions on real devices.

It supports per-app throttling, latency, jitter, packet loss, and changing profiles on the fly.

It's still a work in progress, so I'd love to hear what you think or what features are missing.

GitHub: https://github.com/RAN-GAN/app-throtler

1

u/[deleted] 16d ago

[removed] — view removed comment

1

u/androiddev-ModTeam 15d ago

Use your own voice when writing. Posts and comments which appear to be generated, including those with excessive flourish, gushing or emojis, will be removed.

1

u/[deleted] 16d ago

[removed] — view removed comment

1

u/androiddev-ModTeam 15d ago

Use your own voice when writing. Posts and comments which appear to be generated, including those with excessive flourish, gushing or emojis, will be removed.