4

我们在 Ubuntu 12.04 上使用 Django 1.4 和 PostgreSQL。我们有很多测试,问题是运行测试非常慢,我认为因为对于每个测试,数据库都是从头开始创建的。我想通过使用内存中的数据库(而不是硬盘)运行测试来加快测试速度。我该怎么做?有链接或者教程吗?

4

6 回答 6

9

在 Django 1.9 中,如果你有一个多核处理器,一个很好的选择是 flag:

--parallel

这需要您pip install tblib但会让您在多个内核上同时运行单元测试。(https://docs.djangoproject.com/en/1.10/ref/django-admin/#cmdoption-test-parallel

Django 1.8+ 的另一个不错的选择是 flag:

--keepdb

它重用您的测试数据库,停止每次运行测试时创建一个新的测试数据库所导致的长时间等待。( https://docs.djangoproject.com/en/1.10/ref/django-admin/#cmdoption-test-keepdb

于 2017-03-10T16:56:28.057 回答
3

最好的选择是为您的测试提供一个单独的设置文件。在 settings_test.py 你告诉它使用 sqlite 默认使用内存数据库:

from base_settings import *

DATABASES = {
  'default': {
    'ENGINE': 'django.db.backends.sqlite3',
    'NAME': ':memory'
  }
}

然后通过添加运行您的测试--settings=settings_test

另请参阅 Django 文档:
https ://docs.djangoproject.com/en/dev/topics/testing/overview/#the-test-database

于 2014-03-24T15:09:27.713 回答
2

有几个 SO 线程很有帮助:

我肯定会使用 SQLite 技巧来进行完整性检查,但如果你正在做任何特定于数据库的事情,它会让你发疯:某些 SQL 差异,差异是数据精度等。它也削弱了测试的意义:如果你重新使用测试来向您保证更改将在推送到生产环境后起作用,针对不同的数据库运行它们并不是一个好方法。尽可能尝试使用鼻子来跳过数据库重新创建并优化您的本地 Postgres 设置。您也可以尝试完全避免使用数据库。

最适合我的事情是尝试将测试造成的停机时间视为提出更好更改的机会,并鼓励我在启动测试运行程序之前考虑我正在更改的内容。

于 2014-03-24T15:15:40.977 回答
2

快进到 2016 年,我们在 manage.py 中有一个非常好的选项来加速测试。

--keepdb, -k¶ Django 1.8 中的新功能。在测试运行之间保留测试数据库。这具有跳过创建和销毁操作的优点,这可以大大减少运行测试的时间,尤其是在大型测试套件中。如果测试数据库不存在,它将在第一次运行时创建,然后为每次后续运行保留。在运行测试套件之前,任何未应用的迁移也将应用于测试数据库。

如果您不使用 TransactionTestCase 及其子类,则大部分测试运行时间将来自数据库创建。如果你有大量的迁移,那将是非常糟糕的。但你和避免这一切

 ./manage.py test -k myapp
于 2016-04-23T15:49:06.293 回答
0

不熟悉 python 或 Django,但从概念上讲,您应该能够:

  1. 引导测试时创建数据库并加载一次固定装置
  2. 定义一个保存点。
  3. 在每个测试或一组测试之后,回滚到该保存点。

(如果 ORM 不支持保存点,您可能需要在测试期间覆盖 ORM 的开始/结束事务代码。)

http://www.postgresql.org/docs/current/static/sql-savepoint.html

(我要补充一点,在概念层面上,您的 DBAL 和 ORM 应该在您的测试中被模拟,以便您单独测试您的组件。也就是说,您可能不应该在开始时连接到数据库在你的大多数测试中。)

于 2014-03-24T15:32:27.760 回答
0

您可以简单地将用于测试的数据库更改为 sqlite:

import sys
if 'test' in sys.argv:
    DATABASES['default']['engine'] = 'sqlite3'

请注意,由于数据库之间的某些不兼容,您的某些测试可能会失败,但通常这应该有效。

于 2014-03-24T15:04:33.400 回答