AlarmManager Unit Test using Robolectric 3.0

Alarm Manager feature

AlarmManager is an Android component available since API level 1.

I wanted to use this component in the following scenario :
– automatic and repeated triggers that ignite an operation n times a day
– any new scheduling should cancel previous ones (to avoid unconsistent multiple calls)
– when the device restarts (boot completed), the scheduling should be activated without running the app hosting the AlarmManager.
– the BootComplete operation is not enabled by default, but programatically.

AlarmManager Unit Tests

# Setting alarm

So I created an AlarmController that simply set repeated alarm and activate/desactivate scheduling on bootcomplete

The setAlarm() function simply triggers a broadcast at the given interval (here one hour).

To test this with Robolectric 3.0, we have to use a shadowAlarmManager that will store the parameters of the scheduled Alarm. We can thus simply test the interval set, the trigger time as well as the alarm type (here elapsed_realtime) of the ScheduledAlarm.

# Ensuring one Alarm at a time

Let’s say we call setAlarm() api multiple times (if called for instance during a lifecycle callback). Then, we have to ensure that only one alarm dealing with the same operation is set, avoiding thus any unconsistent and unnecessary mutliple wakes up.

# Checking Operation triggered by the Alarm

To test which PendingIntent operation is triggered by the Alarm, we have to use now a ShadowPendingIntent which will give, once again, extra information, especially regarding the component.

# Checking Operation triggered by the BroadcastReceiver

Our broadcast receiver has 2 goals : setting the alarm if BootCompleted and triggering a service (hosting the operation).

To Unit Test that the service is properly started when broadcast is received, we have, once again, to shadow application so we can access to startedServices.

# Checking BroadcastReceiver will init Alarm on BootCompleted

To Unit Test that the Alarm is properly set onBootComplete, we simply verify, using mockito, the colloboration between the System Under Test (namely the BroadcastReceiver) and the AlarmController

#Activating / Desactivating Broadcast receiver on Demand

As you know, a Broadcast Receiver is a main component of Android Architecture and any receivers should be declared in the Android Manifest. However, let’s suppose we want to activate our broadcast receiver only in a particular scenario  (after an in-app purchase for instance  or only during specific lifecycle callbacks), then how to proceed ?

To do so, we have to declare the Broadcast receiver with the enable=false flag. This gives us the control on programatically enabling/disabling the receiver. Then, we can use the Android PackageManager and set the state of our component (namely the receiver) on demand, as follow :

To Unit Test this with Robolectric 3.0+, we rely on the RobolectricPackageManager accessible through the RuntimeEnvironment object. This will give access to any component state, especially the one we are interested in (our receiver).


Android Unit Test : source code on Github

I have create a new Open Source Project called Android Unit Test including this Alarm Manager testing. This project will gather interesting Android Unit Test scenario using Robolectric 3.0, Juni4.+, Mockito 1.9.+

Writing quality Unit Tests on Android requires sometimes quite struggling. This is why this open source project will help you save some time hopefully.

Lean Startup – Go Startup Smartly

Sharing knowledge is part of my life vision. I have learned from others and learned from experimenting myself too, so passing this to others is the ultimate reward.

Few weeks back, I have been kindly asked by the organizers if I could join the AndroidDeveloperDays 2015 as a speaker. I did the previous edition (speaking about ReactiveProgramming) and was more than happy to participate to this new one. But instead of talking about technical stuff on Android (which is my passion), I wanted to share this time best practices on Startup-ing. The reason why I choosed this topic is the tremendous amount of time that human being is wasting on building « products that nobody wants ». We often forget that our most precious assest in life is our time and our health. Once spent, nobody will give it back to you. So creating a product in condition of extreme uncertainty shouldn’t be done by working blindly hard, but by working smartly. This is all the purpose of this presentation.

Unfortunately, there was a technical issue while recording some talks during AndroidDeveloperDays, and my talk was among the missed one :'( So I can only share with you the slides.
Maybe I’ll give this talk once again one day so I’ll share the video too.

Android Developer Days 2015