如何在 Heroku 上运行 Django 测试

Posted

技术标签:

【中文标题】如何在 Heroku 上运行 Django 测试【英文标题】:How to run Django tests on Heroku 【发布时间】:2012-11-22 05:19:41 【问题描述】:

我有一个部署到 Heroku 的应用程序,我希望能够在目标环境上运行测试套件。我正在使用 Heroku Postgres 插件,这意味着我只能访问单个数据库。我无权创建新数据库,这反过来意味着标准 Django 测试命令失败,因为它无法创建 test_* 数据库。

$ heroku run python manage.py test
Running `python manage.py test` attached to terminal... up, run.9362
Creating test database for alias 'default'...
Got an error creating the test database: permission denied to create database

有没有办法解决这个问题?

【问题讨论】:

【参考方案1】:

原来我错了。我没有测试我认为正在测试的内容...由于 Heroku 的路由网格将请求发送到不同的服务器,LiveServerTestCase 正在一台机器上启动一个 Web 服务器,而 Selenium 则完全连接到其他机器。

通过将 Heroku Procfile 更新为:

web: python src/manage.py test --liveserver=0.0.0.0:$PORT

覆盖DATABASES 设置以指向测试数据库,并自定义链接到下面的测试套件运行器(同样的想法仍然成立:覆盖setup_databases 以便它只删除/重新创建表,而不是整个数据库),我能够运行远程测试。但这更加hacky/痛苦/不雅。还在寻找更好的东西!很抱歉造成混乱。


(下面更新答案)

以下是对我有用的步骤:

使用 Heroku 工具带创建额外的免费 Postgres 数据库

heroku addons:add heroku-postgresql:dev

使用 HerokuTestSuiteRunner 类,您可以找到 here。

此自定义测试运行程序要求您定义遵循典型 DATABASES 格式的 TEST_DATABASES 设置。例如:

TEST_DATABASES = 
    'default': dj_database_url.config(env='TEST_DATABASE_URL')

然后,将TEST_RUNNER 设置为可以找到 HerokuTestSuiteRunner 的 Python 路径。

您现在应该能够使用给定的数据库在 Heroku 上运行 Django 测试。这是一个非常快速的黑客攻击......让我知道如何改进/减少黑客攻击。享受吧!


(原答案如下)

已经讨论了一些相关的解决方案here。正如您在Django docs 中看到的,“[当]使用 SQLite 数据库引擎时,测试将默认使用内存数据库”。

虽然这并不能彻底测试您在 Heroku 上使用的数据库引擎(我仍在寻找能够做到这一点的解决方案),但将数据库引擎设置为 SQLite 至少可以让您运行测试.

请参阅上面链接的 *** question 以获取一些提示。至少有两种方法:在强制 SQLite 作为数据库引擎之前测试 if 'test' in sys.argv,或者在测试中使用专用设置文件,然后您可以使用 --settings 选项将其传递给 django manage.py test

【讨论】:

谢谢 Greg - 使用 SQLite 并不是一个真正的选择 - 我们遇到了一些可怕的问题,这些问题是由 SQLite 通过的测试(无约束/一致性检查)导致的,这些问题随后在现场被炸毁。当前的解决方案是在 VM 中尽可能接近地复制 Heroku(使用 Vagrant)并在那里运行它们。效果很好,到目前为止还没有发生任何灾难。 谢谢雨果,很高兴知道。我也不会使用 SQLite 进行测试(因为我在生产中使用 Postgres)。为什么不在可以运行测试的环境中添加一个额外的免费“heroku-postgresql:dev”数据库?据我所知,同一个插件可以有多个实例。 感谢您的测试!但我们不要放弃! :-) 查看django.test 源代码,似乎从DjangoTestSuiteRunner 继承并覆盖setup_databasesteardown_databases 可以解决问题,不是吗?今晚无法测试,但我期待很快。随意击败我! 请查看我对答案的编辑,使用更彻底、与 Postgres 兼容的解决方案。 gist.github.com/cordery/d52d9ba44541fabaf4b012f4e62d675b 上有一个关于这个主题的非常有用的对话【参考方案2】:

从 1.8 版开始,Django 现在有一个名为 keepdb 的选项,它允许在测试期间重复使用相同的数据库。

--keepdb 选项可用于在测试运行之间保留测试数据库。

这具有跳过创建和销毁操作的优点,这可以大大减少运行测试的时间,尤其是大型测试套件中的测试。

如果测试数据库不存在,它将在第一次运行时创建,然后为每次后续运行保留。

在运行测试套件之前,任何未应用的迁移也将应用于测试数据库。

由于它还允许在运行测试之前存在测试数据库,因此您只需将一个新的 Postgres Heroku 实例添加到您的 dyno 并配置测试以使用该特定数据库。

奖励:您还可以使用 failfast 选项,该选项会在您的第一个测试崩溃后立即退出,这样您就不必等待所有测试完成。

但是,如果您将内容部署到 Heroku 并且您正在使用 Heroku Pipelines,则可以使用更好的选择:Heroku CI。

【讨论】:

以上是关于如何在 Heroku 上运行 Django 测试的主要内容,如果未能解决你的问题,请参考以下文章

在 Heroku 上运行 Django/React 应用程序时,如何让 collectstatic 工作?

如何调试使用 whitenoise、gunicorn 和 heroku 服务的 django 静态文件?

如何在 heroku 上部署 django+swamp dragon 实时聊天应用程序?

如何使用 Heroku 和 Django 实现简单的 cron 作业

如何调试带有whitenoise,gunicorn和heroku的Django静态文件?

为啥我的 Django 应用程序可以在本地运行,但不能在 Heroku 上运行?