我正在尝试在Django的单元测试框架中测试一些芹菜功能,但每当我尝试检查AsyncResult时,测试就像从未启动过一样。
我知道这段代码在RabbitMQ的真实环境中工作,所以我只是想知道为什么它在使用测试框架时不起作用。
以下是一个例子:
@override_settings(CELERY_EAGER_PROPAGATES_EXCEPTIONS = True,
CELERY_ALWAYS_EAGER = True,
BROKER_BACKEND = 'memory',)
def test_celery_do_work(self):
result = myapp.tasks.celery_do_work.AsyncResult('blat')
applied_task = myapp.tasks.celery_do_work.apply_async((), task_id='blat')
applied_task.wait()
# THIS SUCCEEDS
self.assertTrue(applied_task.successful())
# THIS FAILS
self.assertTrue(result.successful())
使用ALWAYS_EAGER选项是否会禁用AsyncResult功能,因为它正在立即执行?如果是这样,有没有办法能够单元测试AsyncResult状态检查?如果我尝试取出ALWAYS_EAGER选项,测试永远不会运行,所以我不知所措。
谢谢!
答案 0 :(得分:13)
当CELERY_ALWAYS_EAGER
为True
时,对apply_async()
的调用实际上已替换为apply()
。返回的结果是EagerResult
,它已包含您的任务结果。
所以,是的,设置ALWAYS_EAGER = True
会禁用整个AsyncResult
功能。绕过整个异步过程,并且实际上没有任务发送到代理,这就是您无法通过AsyncResult
检索结果的原因。
在测试只需要Celery结果的代码路径时使用CELERY_ALWAYS_EAGER = True
,并以EagerResult
或AsyncResult
的方式工作。
如果需要,有一种方法可以使用AsyncResult
和CELERY_ALWAYS_EAGER = False
运行测试,但为此,您需要在测试用例中调用任务之前启动工作程序。然后,工作人员将能够执行您的任务,AsyncResult
将正常工作。你可以看看django-celery-testworker这似乎就是这样,虽然我没有测试过。