让Celery使用Django的测试数据库而不使用task_always_eager

时间:2017-02-05 22:57:06

标签: python django unit-testing celery

在使用Celery任务的Django应用程序中运行测试时,我无法完全测试需要从数据库获取数据的任务,因为他们没有连接到Django创建的测试数据库。

将Celery中的task_always_eager设置为True可以部分解决此问题,但正如documentation for testing所述,这并不能完全反映代码如何在真正的Celery工作人员上运行不适合测试。

如何在不设置task_always_eager = True的情况下运行Django测试时使Celery任务使用Django测试数据库?

2 个答案:

答案 0 :(得分:13)

短=您必须在生产中运行芹菜工作者

易:

  1. 使用专用测试数据库(如生产中)
  2. 配置芹菜使用它
  3. 在运行测试之前手动启动芹菜工作者
  4. 高级:

    1. 使用自动创建的测试数据库(可能是sqlite)
    2. 在测试setUp()
    3. 中运行celery worker
    4. 配置芹菜使用自动创建的测试数据库(从测试过程复制django.conf.settings.DATABASE到芹菜)
    5. 总是必须为芹菜提供消息代理。

      我有一个测试需要专门的芹菜工作者来检查我在celery任务和调用代码之间传递消息的代码: https://gist.github.com/Sovetnikov/a7ad982fc77e8dfbc528bfc20fcf3b1e 这个python模块是二合一的 - 一个具有自包含配置的TestUnit和芹菜工作者运行器。

      我的代码不使用任何数据库,但您可以根据需要轻松调整它。只需将django.conf.settings.DATABASE(作为json或pickle或任何你喜欢的方法)传递给celery starter代码并配置Django DATABASE以指向测试db。

      其他信息

      1. 这个案例有完整的解决方案https://github.com/RentMethod/celerytest(我试过了 它的一些旧版本并没有运气,因为它使用线程,使用python GIL ......我认为它过于复杂了)

      2. 示例代码,如何在单个模块中配置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标志。

相关问题