一段时间以来,我的单元测试花费了比预期更长的时间。我试着调试了几次,但没有太大的成功,因为延迟甚至在我的测试开始运行之前。这影响了我远程做任何接近测试驱动开发的事情的能力(也许我的期望太高了),所以我想看看我是否可以一劳永逸地解决这个问题。
当运行一个测试时,在开始和实际开始测试之间有70到80秒的延迟。
<... bunch of unimportant print messages I print from my settings>
Creating test database for alias 'default'...
......
----------------------------------------------------------------
Ran 6 tests in 2.161s
OK
Destroying test database for alias 'default'...
real 1m21.612s
user 1m17.170s
sys 0m1.400s
1m:21中的约1m18位于
Creating test database for alias 'default'...
以及
.......
也就是说,测试用了不到3秒的时间,但是数据库初始化好像用了1分18秒
我有大约30个应用程序,大多数都有1到3个数据库模型,所以这应该给予你了解项目的大小。我使用SQLite进行单元测试,并实现了一些建议的改进。我不能发布我的整个设置文件,但很高兴添加任何需要的信息。
我用的是跑步机
from django.test.runner import DiscoverRunner
from django.conf import settings
class ExcludeAppsTestSuiteRunner(DiscoverRunner):
"""Override the default django 'test' command, exclude from testing
apps which we know will fail."""
def run_tests(self, test_labels, extra_tests=None, **kwargs):
if not test_labels:
# No appnames specified on the command line, so we run all
# tests, but remove those which we know are troublesome.
test_labels = (
'app1',
'app2',
....
)
print ('Testing: ' + str(test_labels))
return super(ExcludeAppsTestSuiteRunner, self).run_tests(
test_labels, extra_tests, **kwargs)
在我的设置中:
TEST_RUNNER = 'config.test_runner.ExcludeAppsTestSuiteRunner'
我还尝试过将django-nose
与django-nose-exclude
一起使用
我读了很多关于如何加快测试速度的文章,但是没有找到任何关于如何优化或避免数据库初始化的线索。我看到了关于尽量不使用数据库测试的建议,但是我不能或不知道如何完全避免。
请让我知道如果
1.这是正常的,也是意料之中的
1.不期望(希望有修复或引导该做什么)
同样,我不需要关于如何加速测试本身的帮助,但需要初始化(或开销)。我希望上面的例子需要10秒而不是80秒。
非常感谢
我使用--verbose 3
运行测试(针对单个应用程序),发现这都与迁移有关:
Rendering model states... DONE (40.500s)
Applying authentication.0001_initial... OK (0.005s)
Applying account.0001_initial... OK (0.022s)
Applying account.0002_email_max_length... OK (0.016s)
Applying contenttypes.0001_initial... OK (0.024s)
Applying contenttypes.0002_remove_content_type_name... OK (0.048s)
Applying s3video.0001_initial... OK (0.021s)
Applying s3picture.0001_initial... OK (0.052s)
... Many more like this
我把所有的迁移都压扁了,但还是很慢。
6条答案
按热度按时间rkue9o1l1#
解决我的问题的最终解决方案是强制Django在测试期间禁用迁移,这可以通过如下设置来完成
或使用https://pypi.python.org/pypi/django-test-without-migrations
我的整个测试现在需要大约1分钟,一个小应用程序需要5秒。
在我的例子中,测试不需要迁移,因为我在迁移时更新测试,也不使用迁移来添加数据。
sz81bmfz2#
摘要
使用
pytest
!操作
pip install pytest-django
pytest --nomigrations
而不是./manage.py test
结果
./manage.py test
花费2分钟11.86秒pytest --nomigrations
花费2.18秒提示
pytest.ini
的文件,并在那里指定默认的命令行选项和/或Django设置。现在,您可以简单地使用
pytest
运行测试,并保存一些输入。--reuse-db
添加到默认命令行选项来进一步加快后续测试的速度。但是,一旦更改了数据库模型,就必须运行一次
pytest --create-db
来强制重新创建测试数据库。pytest
的文件,包含以下内容,将执行位强制转换到它(chmod +x pytest
),然后运行./pytest
而不是pytest
进行测试:您可以创建一个
test_gevent.py
文件来测试gevent monkey补丁是否成功:参考资料
mepcadol3#
当manage.py迁移文件中没有更改时,使用./ www.example.com test --keepdb
nzkunb0c4#
数据库初始化确实需要太长时间...
我有一个项目,大约有相同数量的模型/表(大约77),大约350个测试,总共需要1分钟来运行所有内容。在一个分配了2个CPU和2GB内存的流浪机器上开发。我还使用py.test和pytest-xdist插件并行运行多个测试。
你可以做的另一件事是告诉django重用测试数据库,只有当你有模式更改时才重新创建它。你也可以使用SQLite,这样测试将使用内存中的数据库。这两种方法都在这里解释:https://docs.djangoproject.com/en/dev/topics/testing/overview/#the-test-database
EDIT:如果上面的选项都不起作用,还有一个选项是让你的单元测试继承django SimpleTestCase,或者使用一个不创建数据库的自定义测试运行器,如这里的答案所解释的:django unit tests without a db。
然后你可以使用像这样的库来模拟django对数据库的调用(这是我写的):https://github.com/stphivos/django-mock-queries
通过这种方式,您可以在本地快速运行单元测试,让CI服务器在将代码合并到某个稳定的dev/master分支(不是生产分支)之前,担心运行需要数据库的集成测试。
gywdnpxw5#
我也遇到了问题,我所做的一个解决方案是子类化Django.TestCase --〉创建Django.TestCase的子类
并覆盖了如下方法:
@classmethod def _databases_support_transactions(cls):return真
后端数据库是apache cassandra..
a6b3iqyw6#
如果你使用的是Postgres,使用一个Postgres模板来保存一个空数据库的拷贝,然后配置Django在测试数据库创建时使用这个模板。
一种方法是:
1.使用
--keepdb
参数运行Django的test命令。1.在Postgres上,使用查询重命名创建的测试数据库
alter database "test_your_db_name" rename to "test_your_db_name_template";
1.在Postgres上,使用查询将数据库设置为模板
alter database "test_your_db_name_template" IS_TEMPLATE = true
1.使用以下方法调整测试设置:
1.在不使用
--keepdb
参数的情况下再次运行Django测试。由于迁移已经应用到模板数据库,因此它们不必再次运行,因此测试将立即开始。另请参阅文档: