Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I test my JobService with an Instrumentation test?

I have a JobService that is properly implemented and works fine in simple cases but I want to ensure the service is properly tested in all conditions.

I'd like to use an Instrumentation test case so that I can test the full flow from the scheduling of the job with getSystemService(JobScheduler.class).schedule(job) to the invocation of onCreate in my JobService and my onStartJob/onStopJob calls.

My JobService launches AsyncTasks sometimes (thereby returning true in onStartJob) and other times it returns false for work that's already done. I have various calls to jobFinished(mJobParameters, needsReschedule) and I'd like to ensure that they work properly as well.

I've been trying to get instrumentation tests working for the past couple days but the best I've been able to come up with is a test that schedules the job but the job never leaves the pending state. I have tried various configurations of waits/background threads to see if freeing the UI thread is what's needed but haven't had any success.

It also doesn't appear that Google has surfaced anything to properly test the full flow of this component which is surprising, given how they seem to be forcing everyone to use it as newer APIs are released.

I've seen What tools are available to test JobScheduler? but it's difficult to automate with adb (and I'm not interested in answers that use it).

Does anyone know a way to end to end test a JobService with the JobScheduler using Instrumentation tests?

like image 573
Reuben Tanner Avatar asked Jun 08 '17 19:06

Reuben Tanner


People also ask

What is an instrumentation test?

Instrumented tests are tests that run on physical devices and emulators, and they can take advantage of the Android framework APIs and supporting APIs, such as AndroidX Test.

How do I test my job scheduler?

Use this JOB_ID to force the job to run. You can do this by using the adb shell cmd jobscheduler run command, (requires Android 7.1 or higher). Don't forget the -f option as this forces the job to run even if the restrictions set are not met.


1 Answers

Thanks to the Google devs being very responsive to answer my question here: https://issuetracker.google.com/issues/62543492, it's now clear how to do it!

It appears that part of the set up of the instrumentation test examples they provided is setting the running app as active and mostly learning about job state via cmd jobscheduler <command> invocations on the shell from the test

    try {
        SystemUtil.runShellCommand(getInstrumentation(), "cmd activity set-inactive "
                + mContext.getPackageName() + " false");
    } catch (IOException e) {
        Log.w("ConstraintTest", "Failed setting inactive false", e);
    }

See the provided InstrumentationTestCase subclass they posted in the bug notes

like image 76
Reuben Tanner Avatar answered Sep 28 '22 00:09

Reuben Tanner