[英]Models inside tests - Django 1.7 issue
I'm trying to port my project to use Django 1.7. 我正在尝试移植我的项目以使用Django 1.7。 Everything is fine except 1 thing. 一切都很好,除了一件事。 Models inside tests folders. 测试文件夹内的模型。
Django 1.7 new migrations run migrate command internally. Django 1.7新迁移在内部运行migrate命令。 Before syncdb was ran. 在syncdb运行之前。 That means if a model is not included in migrations - it won't be populated to DB (and also to test DB). 这意味着如果模型未包含在迁移中 - 它将不会填充到DB(以及测试数据库)。 That's exactly what I'm experiencing right now. 这正是我现在所经历的。
What I do is: 我所做的是:
In my /app/tests/models.py
I have dummy model: class TestBaseImage(BaseImage): pass
All it does is to inherit from an abstract BaseImage
model. 在我的/app/tests/models.py
我有一个虚拟模型: class TestBaseImage(BaseImage): pass
它所做的只是从一个抽象的 BaseImage
模型继承。
Then in tests I create instances of that dummy model to test it. 然后在测试中我创建该虚拟模型的实例来测试它。
The problem is that it doesn't work any more. 问题是它不再起作用了。 It's not included in migrations (that's obvious as I don't want to keep my test models in a production DB). 它不包含在迁移中(这很明显,因为我不想将我的测试模型保存在生产数据库中)。 Running my tests causes DB error saying that table does not exist
. 运行我的测试会导致数据库错误,表明该table does not exist
。 That makes sense as it's not included in migrations. 这是有道理的,因为它不包含在迁移中。
Is there any way to make it work with new migrations system? 有没有办法让它适用于新的迁移系统? I can't find a way to "fix" that. 我找不到一种“修复”的方法。
Code I use: 我使用的代码:
app/tests/models.py 应用程序/测试/ models.py
from ..models import BaseImage
class TestBaseImage(BaseImage):
"""Dummy model just to test BaseImage abstract class"""
pass
app/models.py 应用程序/ models.py
class BaseImage(models.Model):
# ... fields ...
class Meta:
abstract = True
factories: 工厂:
class BaseImageFactory(factory.django.DjangoModelFactory):
"""Factory class for Vessel model"""
FACTORY_FOR = BaseImage
ABSTRACT_FACTORY = True
class PortImageFactory(BaseImageFactory):
FACTORY_FOR = PortImage
example test: 示例测试:
def get_model_field(model, field_name):
"""Returns field instance"""
return model._meta.get_field_by_name(field_name)[0]
def test_owner_field(self):
"""Tests owner field"""
field = get_model_field(BaseImage, "owner")
self.assertIsInstance(field, models.ForeignKey)
self.assertEqual(field.rel.to, get_user_model())
There is a ticket requesting a way to do test-only models here 有一张票要求在这里进行仅测试模型的方法
As a workaround, you can decouple your tests.py and make it an app. 作为一种解决方法,您可以将tests.py解耦并使其成为应用程序。
tests
|--migrations
|--__init__.py
|--models.py
|--tests.py
You will end up with something like this: 你最终会得到这样的东西:
myapp
|-migrations
|-tests
|--migrations
|--__init__.py
|--models.py
|--tests.py
|-__init__.py
|-models.py
|-views.py
Then you should add it to your INSTALLED_APPS
然后你应该把它添加到你的INSTALLED_APPS
INSTALLED_APPS = (
# ...
'myapp',
'myapp.tests',
)
You probably don't want to install myapp.tests
in production, so you can keep separate settings files. 您可能不希望在生产中安装myapp.tests
,因此您可以保留单独的设置文件。 Something like this: 像这样的东西:
INSTALLED_APPS = (
# ...
'myapp',
)
try:
from local_settings import *
except ImportError:
pass
Or better yet, create a test runner and install your tests there. 或者更好的是,创建一个测试运行器并在那里安装测试。
Last but not least, remember to run python manage.py makemigrations
最后但同样重要的是,请记住运行python manage.py makemigrations
Here's a workaround that seems to work. 这是一个似乎有效的解决方法。 Trick the migration framework into thinking that there are no migrations for your app. 欺骗迁移框架,认为您的应用没有迁移。 In settings.py
: 在settings.py
:
if 'test' in sys.argv:
# Only during unittests...
# myapp uses a test-only model, which won't be loaded if we only load
# our real migration files, so point to a nonexistent one, which will make
# the test runner fall back to 'syncdb' behavior.
MIGRATION_MODULES = {
'myapp': 'myapp.migrations_not_used_in_tests'
}
I found the idea on the first post in ths Django dev mailing list thread , and it's also currently being used in Django itself , but it may not work in future versions of Django where migrations are required and the "syncdb fallback" is removed. 我在Django dev邮件列表线程的第一篇文章中找到了这个想法,它目前也在Django本身使用 ,但它可能不适用于需要迁移并删除“syncdb fallback”的Django的未来版本。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.