Coroutines and Idling Resources
Oh coroutines! Where have you been all my life?
Yes, yes. I’m one of those guys who simply fascinated by kotlin coroutines. I’m pretty sure anyone coming from a Java background might be sharing the same sentiments.
Anyway, recently I was writing some UI tests where I had to do some waiting. Data was being fetched from firebase firestore so I had wrapped the firestore callbacks in suspended functions. This issue of waiting while doing UI testing is something that every android engineer has to face eventually because network calls can’t be done on the UI thread. After combing through a couple of articles online, the recommended solutions to the above issue were mocking, faking or simply just waiting it out. For me the third option was obviously a no go. It seemed more of a hack than an actual solution. Mocking really works well when dealing with some kind of rest API or non-firebase source. Faking would do, but that would mean creating an extra class for every firebase integration which seemed like more work.
We are developers, we are supposed to be lazy.
I then remembered reading about Idling Resources, and how it works well with asynchronous operations. In the past, I avoided it because it just added way more code. Can you imagine going through you entire codebase adding triggers for idling resource whenever you are doing an asynchronous call? We ares supposed to lazy.
Enter kotlin, with coroutines:
With kotlin, a lot of stuff can be introduced into an existing while still maintaining the lazy factor.
How? Let me show you:
First of all you need to setup the following two classes:
Checkout the article below for a more detailed explanation:
Now for the fun part!
To make use of the above classes we are gonna use an extension function. Basically we’ll be extending the CoroutineScope class with a new launchIdling function. Here’s the snippet:
We are just triggering the idling resource before the launching the job and triggering it again on job completion. That’s it! If you have a lot of GlobalScope.launch calls in your project you can just find and replace using your IDE. Remember to only replace the parent call, not the children.
I still feel that more can be done. I’ll be experimenting to see if better integration can be achieved, especially for complex scenarios. There was a discussion about it earlier, but it seems there hasn’t been any activity for the last couple of months. Below is the repo with the demo code:
Happy New Year!