在使用Celery任务的Django应用程序中运行测试时,我无法完全测试需要从数据库获取数据的任务,因为他们没有连接到Django创建的测试数据库。
将Celery中的task_always_eager
设置为True
可以部分解决此问题,但正如documentation for testing所述,这并不能完全反映代码如何在真正的Celery工作人员上运行不适合测试。
如何在不设置task_always_eager = True
的情况下运行Django测试时使Celery任务使用Django测试数据库?
答案 0 :(得分:13)
短=您必须在生产中运行芹菜工作者
易:
高级:
总是必须为芹菜提供消息代理。
我有一个测试需要专门的芹菜工作者来检查我在celery任务和调用代码之间传递消息的代码: https://gist.github.com/Sovetnikov/a7ad982fc77e8dfbc528bfc20fcf3b1e 这个python模块是二合一的 - 一个具有自包含配置的TestUnit和芹菜工作者运行器。
我的代码不使用任何数据库,但您可以根据需要轻松调整它。只需将django.conf.settings.DATABASE(作为json或pickle或任何你喜欢的方法)传递给celery starter代码并配置Django DATABASE以指向测试db。
其他信息:
这个案例有完整的解决方案https://github.com/RentMethod/celerytest(我试过了 它的一些旧版本并没有运气,因为它使用线程,使用python GIL ......我认为它过于复杂了)
示例代码,如何在单个模块中配置DATABASE设置和init django本身https://gist.github.com/Sovetnikov/369a8d05ba2b6482fa20769bc498f122
答案 1 :(得分:1)
一个简单的解决方案是use celery.contrib.testing.worker.start_worker
to spawn a Celery worker within the Django test process。因为它存在于同一个进程中,所以它可以访问默认的内存中测试数据库,但因为它存在于自己的线程中,所以它并不急切,并且不需要或建议使用task_always_eager
标志。