【问题标题】:Django unit test query against production database针对生产数据库的 Django 单元测试查询
【发布时间】:2016-12-19 18:21:58
【问题描述】:

我正在尝试为我的 Django 应用程序中的异步方法编写一些单元测试。本质上,当用户执行某个 POST 时,此方法会启动,因此应用程序不会挂起。我要测试的是在运行时取消此请求的能力(在这种情况下通过 celery)。这样做的唯一问题是因为 Celery 独立于 Web 应用程序运行,它将结果推送到真实数据库,而不是由 Django 单元测试创​​建的测试数据库。所以我想知道的是我怎么能做类似的事情

Results.objects.get(id=some_id)

并告诉它指向实际的数据库。我已经尝试过以下方法:

Results.objects.using('default').get(id=some_id)

认为也许这会解决问题,但它没有找到结果(再次因为它将信息推送到实际数据库,而不是测试数据库)。我做了一些搜索,找到了这个链接: How do I run a unit test against the production database? 但这里的答案说“你不应该针对生产进行测试”。我完全理解这不是好的做法,但我需要访问实时数据库。一切都在虚拟机上运行,​​所以无论如何它都是一个测试数据库。有谁知道打到真实数据库的方法吗?

谢谢,

【问题讨论】:

  • 你是如何开始你的芹菜工人的??

标签: python django unit-testing celery integration-testing


【解决方案1】:

我们可以做一件事,一个肮脏的把戏!

  • 在使用 say 的设置上运行 celery worker 和调度程序 'new_one' 数据库。
  • 你应该有一个这样的 settings.py -

    DATABASES = {
       'default': {
           'TEST': {
               'NAME': 'new_one',
           },
       } 
    } 
    db_from_env = dj_database_url.config(default=config('DATABASE_URL'))
    DATABASES['default'].update(db_from_env)
    
  • 然后在另一个数据库上运行你的 django 服务器说
    'another_new_one'。

  • 运行您的测试用例,它们会通过。为什么?测试用例正在使用 'new_one' 数据库,celery 也使用 'new_one' 数据库,你的 使用“another_new_one”的 django 服务器。干杯!
  • 我尝试为测试和生产提供相同的名称 数据库,但运行测试数据库时出现错误 已经被其他人使用',其他人是 django 服务器。所以需要两个不同的数据库,1-new_one 2-another_new_one

      Note- I have used .env file to use config(), where I have my production database name host user password etc. It can change according to what you use. Just use two different databases and do this dirty trick, it will work. As it worked for me.
    

【讨论】:

    【解决方案2】:

    如果你真的想从单元测试中运行专用的 celery worker 进程,那么你需要从 setUp() (或任何你想要的方法)启动 celery worker 并将 django.conf.settings.DATABASE 从测试进程复制到 celery worker过程。

    对于起点,请参阅我对非常相似的问题 https://stackoverflow.com/a/42107423/590233 的回答(有启动 celery worker 的代码)

    这是在单个模块 https://gist.github.com/Sovetnikov/369a8d05ba2b6482fa20769bc498f122 中配置 django 和 DATABASE 设置的示例代码

    只需结合两种技术,你就会得到你想要的。

    【讨论】:

      【解决方案3】:

      我不确定针对您的产品进行测试是否比针对您的测试数据库在开发模式下运行您的 celery worker 更好的解决方案。你是如何开始你的芹菜工人的?我想你正在使用你的 prod/real 设置在测试之外启动你的芹菜工人,然后你正在使用测试设置运行你的测试。对于集成测试,如果您有集成环境,它可能会更加可重复/可维护。

      一个常见的测试策略是:

      • 单元测试您的视图以确保它使用正确的参数调用正确的 celery 任务,您可以删除 celery 任务依赖项,或者您可以使用 CELERY_ALWAYS_EAGER=True 和内存队列同步运行 celery 任务。
      • 如果你 stub 了 celery 依赖项,那么应该有一个单独的单元测试来执行它的逻辑

      由于 celery 代理的进程间依赖性,您的原始场景不太适合 django 单元测试框架。您的应用程序和 celery 之间的集成测试可能很有价值,但要使其可维护、可重复和可靠 celery 代理进程启动、清理等可能应该以自动化方式进行管理。

      【讨论】:

      • 理想情况下,我可以同步运行 celery 任务。不幸的是,程序的编码方式,它必须在单元测试中异步运行,因为它不断检查某个对象的状态。如果此对象的字符串字段的值设置为“CANCEL”,则任务在执行过程中被取消。显然,如果我同步运行它,我会遇到无法测试这个“CANCEL”案例的问题。
      猜你喜欢
      • 2020-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-26
      相关资源
      最近更新 更多