← Back to list

Testing User Scenarios Without Polluting App Code (oksnoop)

As Android engineers, we sometimes struggle when testing different user scenarios—and by which I mean behavioral testing. You want to…

Korir Amos · 2025-12-30 07:41 · 4 claps · 2.7 min read paywalled
#android #android-app-development #mocking #okhttp
Open on Medium ↗

Testing User Scenarios Without Polluting App Code (oksnoop)

As Android engineers, we sometimes struggle when testing different user scenarios—and by which I mean behavioral testing. You want to experience the application in a given state, as a certain type of user, under specific conditions. The ideal, traditional approach is to create a test user, ask a backend engineer to modify something in the database, or, worse, hotwire a change directly into your code. I’m pretty sure I pushed a few bugs in my distant past simply because I forgot to remove some “temporary” test logic.

This is a known problem, and there are many ways to approach it. In this case, I wanted something specific: a solution that could be reused across projects, independent of the application itself, and that required no changes to the application source code to integrate. If the app repository had to change, then the solution already felt compromised.

The first idea that came to mind was runtime swapping. What if an external library could hook into application startup, inspect the Koin-provided Retrofit and OkHttp definitions, swap them, and reload the modules? Technically, this worked. In practice, it was fragile. Activities and ViewModels had to be restarted, and occasionally, some requests would slip through before the mocking kicked in. It worked most of the time, which usually means it will fail at precisely the wrong moment.

Runtime intervention was already too late. If OkHttpClient ultimately defines network behaviour, then the safest place to intervene is before the app runs. Compile time, not by modifying the app, but by changing the build.

That’s where oksnoop comes in.

oksnoop is a way to control network behaviour at build time, from outside the application. It does not live in the app, it does not ship with the app, and the application itself is not aware of its existence. Instead of adding debug code, dependencies, or plugins into the project, oksnoop instruments the Gradle build so that the OkHttp client is created with an interceptor already in place when the app is compiled.

Using it doesn’t change how you usually work. You still run the same Gradle tasks you already use — assembleDebug, installDebug, and so on. The only difference is that the build is started with an init script. If that init script is not provided, oksnoop is not included in the build. There’s nothing to remove, nothing to clean up, and nothing that can accidentally leak into production.

Because this happens at build time, there’s no swapping dependencies after startup, no restarting activities, and no hoping that the interceptor kicks in before the first request. By the time the application starts, the network behaviour is already locked in. The first and last requests follow the same rules, making the behaviour predictable and repeatable.

The way behaviour is described is through what oksnoop calls personas. A persona is not just a single mocked endpoint, but a description of a scenario. Instead of thinking “mock this API”, you think “run the app as this type of user” or “run the app under these backend conditions”. Each persona lives outside the application as a JSON file and defines how certain requests should respond — status codes, response bodies, even sequences of responses.

One of the most significant advantages of this approach is what it avoids. There’s no debug-only code creeping into the app. No architectural decisions made purely for testing. No flags scattered around, hoping nobody forgets to turn them off. If oksnoop is not enabled for a build, the application behaves exactly as it normally would.

In practice, oksnoop is just thin build-time instrumentation. It focuses on behaviour, not structure. Personas become a way to describe scenarios in a shared language, while the application stays focused on what it’s supposed to do. Instead of bending the app to make testing possible, the build is where that flexibility lives.

Want to experiment with Oksnoop? Here is the link https://github.com/AmosKorir/oksnoop


메타데이터
post_id
5f3be19c5c8d
slug
testing-user-scenarios-without-polluting-app-code-oksnoop-5f3be19c5c8d
url
https://medium.com/@koriramos/testing-user-scenarios-without-polluting-app-code-oksnoop-5f3be19c5c8d
canonical_url
https://medium.com/@koriramos/testing-user-scenarios-without-polluting-app-code-oksnoop-5f3be19c5c8d
author_url
https://medium.com/@koriramos
status
ok
fetched_at
2026-06-17 14:59:50