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.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *