如何在使用managed = False的Django测试期间创建表
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在使用managed = False的Django测试期间创建表相关的知识,希望对你有一定的参考价值。
我有一个托管= False的模型。
class SampleModel(models.Model):
apple = models.CharField(max_length=30)
orange = models.CharField(max_length=30)
class Meta:
managed = False
我有一个单元测试,它创建了一个SampleModel,但是当我运行测试时,我得到:
DatabaseError: no such table: SAMPLE_SAMPLE_MODEL
django docs - https://docs.djangoproject.com/en/dev/ref/models/options/#managed记录了以下内容:
对于涉及托管= False的模型的测试,由您来确保在测试设置中创建正确的表。
如何在测试设置期间实际“创建”表格?或者,我怎样才能使它在运行测试时,在测试期间该模型具有“managed = True”?
在实际应用程序中,此模型实际上由数据库中的视图支持。但是对于测试期间,我想将其视为一个表,并能够在那里插入测试数据。
看看这篇博客文章:http://www.caktusgroup.com/blog/2010/09/24/simplifying-the-testing-of-unmanaged-database-models-in-django/它详细描述了为非托管模型创建测试运行器。
from django.test.simple import DjangoTestSuiteRunner
class ManagedModelTestRunner(DjangoTestSuiteRunner):
"""
Test runner that automatically makes all unmanaged models in your Django
project managed for the duration of the test run, so that one doesn't need
to execute the SQL manually to create them.
"""
def setup_test_environment(self, *args, **kwargs):
from django.db.models.loading import get_models
self.unmanaged_models = [m for m in get_models()
if not m._meta.managed]
for m in self.unmanaged_models:
m._meta.managed = True
super(ManagedModelTestRunner, self).setup_test_environment(*args,
**kwargs)
def teardown_test_environment(self, *args, **kwargs):
super(ManagedModelTestRunner, self).teardown_test_environment(*args,
**kwargs)
# reset unmanaged models
for m in self.unmanaged_models:
m._meta.managed = False
执行原始SQL以在测试设置中创建表:
from django.db import connection
class MyTest(unittest.TestCase):
def setUp(self):
connection.cursor().execute("CREATE TABLE ...")
def tearDown(self):
connection.cursor().execute("DROP TABLE ...")
使用以下方法创建自己的测试运行器
from django.test.simple import DjangoTestSuiteRunner
class NoDbTestRunner(DjangoTestSuiteRunner):
""" A test runner to test without database creation """
def setup_databases(self, **kwargs):
""" Override the database creation defined in parent class """
#set manage=True for that specific database on here
然后在您的设置上将此类添加到TEST_RUNNER。
如果您没有许多非托管表,请快速修复:
首先在设置中添加一个新变量。
# settings.py
import sys
UNDER_TEST = (len(sys.argv) > 1 and sys.argv[1] == 'test')
然后在模型中
# models.py
from django.conf import settings
class SampleModel(models.Model):
apple = models.CharField(max_length=30)
orange = models.CharField(max_length=30)
class Meta:
managed = getattr(settings, 'UNDER_TEST', False)
不错的即插即用解决方案。只需在测试类定义之前粘贴它即可。 (注意:使用django 1.8)
from django.db.models.loading import get_models
def change_managed_settings_just_for_tests():
"""django model managed bit needs to be switched for tests."""
unmanaged_models = [m for m in get_models() if not m._meta.managed]
for m in unmanaged_models:
m._meta.managed = True
change_managed_settings_just_for_tests()
只需添加:django.db.models.loading.get_models将在Django 1.9中删除(参见https://github.com/BertrandBordage/django-cachalot/issues/33)。
下面是Django 1.10的更新版本:
class UnManagedModelTestRunner(DiscoverRunner):
'''
Test runner that automatically makes all unmanaged models in your Django
project managed for the duration of the test run.
Many thanks to the Caktus Group
'''
def setup_test_environment(self, *args, **kwargs):
from django.apps import apps
self.unmanaged_models = [m for m in apps.get_models() if not m._meta.managed]
for m in self.unmanaged_models:
m._meta.managed = True
super(UnManagedModelTestRunner, self).setup_test_environment(*args, **kwargs)
def teardown_test_environment(self, *args, **kwargs):
super(UnManagedModelTestRunner, self).teardown_test_environment(*args, **kwargs)
# reset unmanaged models
for m in self.unmanaged_models:
m._meta.managed = False
请注意,您还需要注意迁移(请参阅Testing django application with several legacy databases)
MIGRATION_MODULES = {
'news': 'news.test_migrations',
'economist': 'economist.test_migrations'
}
您可以在SchemaEditor方法中使用TestCase.setUp
来明确地使用managed = False
创建模型。
# models.py
from django.db import models
class Unmanaged(models.Model):
foo = models.TextField()
class Meta:
# This model is not managed by Django
managed = False
db_table = 'unmanaged_table'
在你的测试中:
# tests.py
from django.db import connection
from django.test import TestCase
from myapp.models import Unmanaged
class ModelsTestCase(TestCase):
def setUp(self):
super().setUp()
with connection.schema_editor() as schema_editor:
schema_editor.create_model(Unmanaged)
if Unmanaged._meta.db_table not in connection.introspection.table_names():
raise ValueError("Table `{table_name}` is missing in test database.".format(table_name=Unmanaged._meta.db_table))
def tearDown(self):
super().tearDown()
with connection.schema_editor() as schema_editor:
schema_editor.delete_model(Unmanaged)
def test_unmanaged_model(self):
with self.assertNumQueries(num=3):
self.assertEqual(0, Unmanaged.objects.all().count())
Unmanaged.objects.create()
self.assertEqual(1, Unmanaged.objects.all().count())
以上是关于如何在使用managed = False的Django测试期间创建表的主要内容,如果未能解决你的问题,请参考以下文章
在以下任何来源中均未找到插件[id:'io.spring.dependency-management',版本:'1.0.5.RELEASE',apply:false]:
如何在托管 = False 的 Django 测试期间创建表?
./manage.py 对 Django 1.4 的测试给出了在 google appengine 上找不到的 Thing2Literal 导入