我们如何使Django测试更快?
我们在Ubuntu 12.04上使用Django 1.4和PostgreSQL。我们有很多测试,问题是运行测试非常慢,我认为,因为对于每个测试,数据库都是从头创建的。我希望通过在内存(而不是硬盘)中使用数据库来运行测试,从而加快测试速度。我该怎么做?您有任何链接或教程吗?您只需将测试数据库更改为sqlite即可:我们如何使Django测试更快?,django,postgresql,django-testing,in-memory-database,django-tests,Django,Postgresql,Django Testing,In Memory Database,Django Tests,我们在Ubuntu 12.04上使用Django 1.4和PostgreSQL。我们有很多测试,问题是运行测试非常慢,我认为,因为对于每个测试,数据库都是从头创建的。我希望通过在内存(而不是硬盘)中使用数据库来运行测试,从而加快测试速度。我该怎么做?您有任何链接或教程吗?您只需将测试数据库更改为sqlite即可: import sys if 'test' in sys.argv: DATABASES['default']['engine'] = 'sqlite3' 请注意,由于数据库之
import sys
if 'test' in sys.argv:
DATABASES['default']['engine'] = 'sqlite3'
请注意,由于数据库之间的某些不兼容,您的一些测试可能会失败,但通常情况下,这应该是可行的 最好的选择是为您的测试设置一个单独的设置文件。在settings_test.py中,您告诉它使用sqlite,默认情况下,sqlite使用内存中的数据库:
from base_settings import *
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': ':memory'
}
}
然后通过添加--settings=settings\u test
另请参见Django文档:有几个SO线程非常有用:
对我来说,最有效的方法是尝试将测试导致的停机时间视为一个做出更好更改的机会,并鼓励我在启动测试运行程序之前思考正在更改的内容。不熟悉python或Django,但从概念上讲,您应该能够:
(我想补充一点,在概念层面上,您的DBAL和ORM应该在您的测试中被模拟,这样您就可以单独测试您的组件。也就是说,您可能不应该在大多数测试中首先连接到数据库。)快进到2016年,我们在manage.py中有一个非常好的选项来加速测试 --keepdb,-k 在Django 1.8中新增。在测试运行之间保留测试数据库。这样做的优点是可以跳过创建和 销毁可以大大缩短运行测试时间的操作, 尤其是那些在大型测试套件中的测试。如果测试数据库没有 存在时,它将在第一次运行时创建,然后为每个 后续运行。任何未应用的迁移也将应用于 在运行测试套件之前测试数据库 如果您不使用TransactionTestCase及其子类,测试运行时间的很大一部分将来自数据库创建。如果有大量迁移,情况会非常糟糕。但是,你必须避免所有这些
./manage.py test -k myapp
在Django 1.9中,如果您有一个多核处理器,一个很好的选择是标记:
--parallel
--keepdb
这要求您pip安装tblib
,但允许您在多个内核上同时运行单元测试。()
Django 1.8+的另一个不错的选择是标志:
--parallel
--keepdb
它重用您的测试数据库,停止了由于每次运行测试时创建新的测试数据库而导致的长时间等待。(-1.使用SQLite进行测试有什么意义(假定您没有使用任何它无法理解的东西)?如果您使用Postgres部署,您如何确保您的DB相关脚本使用您的测试工作?如果您有任何DB相关脚本,这将不起作用,但对于简单/常规用例来说,这是快速可靠的。如果您担心这两个DB引擎之间的差异,您可以始终在Postgres上运行测试,以检查这里有一些。反对否决票,因为这通常是业务逻辑,而不是需要测试的ORM。当然,原始数据库特定SQL可能会崩溃,但这是一个相当边缘的情况;这必须是手工制作的,您应该知道自己在做什么。在每个单元测试运行中节省8秒(每个开发人员每天数十次!)立即为您节省更多资源。-1.使用SQLite进行测试有什么意义(假定您没有使用任何它不理解的东西)?如果您使用Postgres部署,您如何确保您的DB相关脚本使用您的测试工作?Uri询问如何使用内存数据库优化他的测试,使用sqlite内存数据库进行测试是Django的标准方法。如果他使用Django,您会假设他使用的是Django ORM,这意味着他的应用程序的稳定性应该是数据库无关的(所以使用sqlite进行测试,使用postgres进行部署不是问题——事实上,这是一种常见的做法)。例如,根据我的经验,在内存中使用SQLite运行测试通常会使运行单个测试的时间更长。这尤其是在有大量迁移的情况下,使用内存中的SQLite意味着您需要在每次测试运行时重新执行整个迁移。在永久性Postgres实例中使用
--keepdb
运行通常也同样快或者比内存中的瞬时SQLite更快。使用回滚的问题是,仅在单个事务中进行的任何测试都不可能是非常彻底的测试。@jjanes:因此保存点而不是单个事务:您可以随意嵌套这些事务。但这仍然只在单个事务中有效,不是吗?一旦提交,它无法回滚,在提交之前,一个辅助事务无法看到它。我认为任何完整的测试套件都必须包括多连接可见性/一致性测试。@jjanes:ya,因此需要在测试期间调整ORM代码,而不是发出beg