QA Testing Your App

Axel Springer Tech
Axel Springer Tech
Published in
3 min readMar 17, 2020

--

By aniakarpiuk

Photo by Max Nelson on Unsplash

When developing Android applications, it is a good practice to support slow connections and error handling. This means, there is a loading screen shown, when data is downloaded from the server and an error screen visible, when something went wrong. It might be fine when you are a developer and you are always able to delay or mock responses when implementing those screens, to see the output… but what when you are in QA or a PO who are requested to test the new developments?

QA always has its own ways to test behaviour but it sometimes can be troublesome or not all cases can be easily covered. We, as developers, can help with that with not too much additional work required. I don’t have to mention that a smile on a QA face is priceless.

This proposal depends on the tech stack you use. Our basic library for requests is OkHttp. We also use it to prepare additional features for testing our app.

The basic idea is to use custom interceptors to emulate request errors or delays. It doesn’t need to be anything fancy. You can implement a basic UI to setup how often the requests should fail. Then the interceptor will read this value and emulate an error accordingly. Here is a basic implementation of it.

But first prepare the UI to configure failures or delays. You can use the debug mode and show it in your app settings (if the app is not in release flavour):

Next, prepare an interceptor which will modify responses according to the new settings (you can use regular preferences to pass values between objects).

The delay intercept method could look like this:

@Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
try {
Thread.sleep(preferences.debugRequestDelay)
} catch (e: InterruptedException) {
Log.w("ErrorInterceptor", "Thread is not tired, doesn't want to go to sleep: $e")
}
return chain.proceed(request)
}

…and Error interceptor:

@Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
val response = chain.proceed(request)
return if (shouldFail(request))
createErrorResponse(request, chain.connection()!!.handshake())
else
response
}private fun shouldFail(request: Request): Boolean =
preferences.debugFailureProbability > randomIntprivate val randomInt: Int
@IntRange(from = 0, to = 99)
get() = Random().nextInt(100)private fun createErrorResponse(request: Request,
handshake: Handshake?): Response =
Response.Builder()
.request(request)
.message("Fake debug error")
.body(createEmptyBody())
.protocol(Protocol.HTTP_2)
.code(code)
.handshake(handshake)
.build()

Now you are ready to add interceptors when you create the OkHttpClient:

OkHttpClient
.newBuilder()
....
.addInterceptor(delayInterceptor)
.addInterceptor(errorInterceptor)
.build()

And that’s it!

Kudos to Tomek, one of our former Android devs, who introduced this feature but was too shy to share it with the world.

This article was originally published on upday devs blog.

--

--