Android Jetpack WorkManager - 测试唯一周期任务执行

3
我正在使用Android的Jetpack WorkManager来安排一些每天定期下载任务。我按照说明操作,当工作排队时返回Success
val work = PeriodicWorkRequestBuilder<UpdateWorker>(1, TimeUnit.DAYS)
            .setConstraints(constraints) // Internet connection, idle and battery not low
            .addTag("ANNOUNCEMENTS_WORKER_TAG")
            .build()

val workOperation = workManager.enqueueUniquePeriodicWork("UPDATE_WORK_TAG", ExistingPeriodicWorkPolicy.KEEP, work)

workOperation.state.observe(this, Observer { state ->
    Timber.d("state: $state") // is successful
})

我现在怎么知道这真的在发生?我如何(单元)测试我的任务的重复执行?

5个回答

1
您可以在WorkManager上编写仪器测试:
@RunWith(AndroidJUnit4::class)
class UpdateWorkerTest{

    private lateinit var context: Context

    @Before
    fun setUp() {
        context = ApplicationProvider.getApplicationContext()
    }

    @Test
    fun testWorkerCall() {
        val yourWorker = TestListenableWorkerBuilder<UpdateWorker>(context).build()
        runBlocking {
            val result = yourWorker.doWork()
            assertThat(result, `is`(ListenableWorker.Result.success()))
        }
    }

}

我现在怎么知道这确实正在发生?

你必须相信 Google 团队,并希望你没有使用 One Plus 设备。

出于自己的考虑,你可以尝试操作一下你的设备,例如关闭再打开,然后等待作业运行(在控制台上查看日志)等。

有关测试的更多信息,请参见 文档


0

感谢您的回答和努力!但这不是我要找的。我不想测试我的Worker任务,我想测试我的Worker随时间的定期执行。那么我的Worker每天是否真的会被触发? - Paul Spiesberger

0
首先,请记住您设置的时间间隔是两次 Worker 连续执行之间的最短时间间隔。 WorkManager 会根据约束条件和电池策略(待机模式等)来调整执行时间。最终结果是,您的 Worker 的执行时间会发生变化(第一次在早上6点执行,下一次在早上6:21执行,然后在早上6:34执行,等等)。这在 PeriodicWorkRequest reference 中有解释。
一旦您将WorkRequest加入队列,可以使用LiveData(来自Operation对象)观察其状态,就像您正在执行的那样,或者使用 getWorkInfosForUniqueWorkLiveData 请求WorkInfo。通过这种方式,您可以获取WorkRequest的状态更新(BLOCKED -> ENQUEUED -> RUNNING -> SUCCEEDED / FAILED ,在任何时候,状态可以转换为CANCELLED)。 您可以在此博客上获取有关如何观察WorkRequest状态的更多信息。

感谢您的有效回答。但是我的问题更关注于对我的每日工作程序进行单元测试。我已经通过LiveData订阅了该操作,但这并不能帮助我验证“每24小时执行一次”的情况。所以问题是:我的工作程序是否真的会每天触发? - Paul Spiesberger

0
兄弟,你必须测试你的代码而不是 WorkManager 框架。所以你必须在你的代码中创建一个像这样的方法:
val ONE_DAY_IN_MILLIS = 86400000fun createWorker() : WorkRequest {

    val work = PeriodicWorkRequestBuilder<SendDataWorker>(ONE_DAY_IN_MILLIS, TimeUnit.MILLISECONDS)
            .setConstraints(constraints) // Internet connection, idle and battery not low
            .addTag("ANNOUNCEMENTS_WORKER_TAG")
            .build()
}

并编写一个测试方法来测试它:

val work = createPeriodicWorkRequest()
assertEquals(work.workSpec.intervalDuration, ONE_DAY_IN_MILLIS)

createPeriodicWorkRequest() 的实现是什么? - Karan Sharma

-1

正如您可以在官方文档中阅读到的那样,WorkManager是一个API,它确保在满足所有约束条件的情况下执行。约束条件可以由您设置,例如“具有互联网连接”,但您还应该记住操作系统也有自己的约束条件,例如“不处于Doze模式”。

如果任何约束条件未得到满足,API将在下一个时间段内再次尝试。

简而言之,正如Google所说:

“WorkManager适用于可延迟执行的任务,即不需要立即运行,并且即使应用程序退出或设备重新启动,也需要可靠地运行。”

因此,该API不能确保您在精确的时间运行代码,但确保尽快执行,始终牢记约束条件和重复间隔。

这意味着您不需要测试API本身,而是需要测试Worker内部的代码。同样,如果Activity在顶部,则无需测试“onResume”方法是否已被调用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接