Ber*_*ant 22 django unit-testing django-models abstract
我需要为抽象基础模型编写一些单元测试,它提供了其他应用程序应该使用的一些基本功能.为了测试目的,有必要定义一个继承它的模型; 是否有任何优雅/简单的方法来定义该模型仅用于测试?
我看到一些"黑客"使这成为可能,但从未在django文档或其他类似的地方看到过"官方"方式.
小智 17
我自己偶然发现了这个功能:您可以在tests.py中继承您的抽象模型并像往常一样进行测试.当您运行'manage.py tests'时,Django不仅会创建测试数据库,还会验证和同步您的测试模型.
用当前的Django trunk(版本1.2)测试它.
小智 10
我也有同样的情况.我最终使用了@dylanboxalot解决方案的版本.在阅读"测试结构概述"部分后,请从此处获得更多详细信息.
在setUp
与tearDown
每次测试运行时间的方法被调用.更好的解决方案是在运行所有测试之前运行一次"抽象"模型的创建.为此,您可以实现setUpClassData
并实现tearDownClass
.
class ModelMixinTestCase(TestCase):
'''
Base class for tests of model mixins. To use, subclass and specify the
mixin class variable. A model using the mixin will be made available in
self.model
'''
@classmethod
def setUpClass(cls):
# Create a dummy model which extends the mixin
cls.model = ModelBase('__TestModel__' +
cls.mixin.__name__, (cls.mixin,),
{'__module__': cls.mixin.__module__}
)
# Create the schema for our test model
with connection.schema_editor() as schema_editor:
schema_editor.create_model(cls.model)
super(ModelMixinTestCase, cls).setUpClass()
@classmethod
def tearDownClass(cls):
# Delete the schema for the test model
with connection.schema_editor() as schema_editor:
schema_editor.delete_model(cls.model)
super(ModelMixinTestCase, cls).tearDownClass()
Run Code Online (Sandbox Code Playgroud)
可能的实现可能如下所示:
class MyModelTestCase(ModelMixinTestCase):
mixin = MyModel
def setUp(self):
# Runs every time a test is run.
self.model.objects.create(pk=1)
def test_my_unit(self):
# a test
aModel = self.objects.get(pk=1)
...
Run Code Online (Sandbox Code Playgroud)
也许ModelMixinTestCase
类应该添加到Django?:P
小智 8
我最近偶然发现了这个并希望为更新的Django版本(1.9及更高版本)更新它你可以使用SchemaEditor create_model
而不是过时的sql_create_model
from django.db import connection
from django.db.models.base import ModelBase
from django.test import TestCase
class ModelMixinTestCase(TestCase):
"""
Base class for tests of model mixins. To use, subclass and specify
the mixin class variable. A model using the mixin will be made
available in self.model.
"""
def setUp(self):
# Create a dummy model which extends the mixin
self.model = ModelBase('__TestModel__' + self.mixin.__name__, (self.mixin,), {'__module__': self.mixin.__module__})
# Create the schema for our test model
with connection.schema_editor() as schema_editor:
schema_editor.create_model(self.model)
def tearDown(self):
# Delete the schema for the test model
with connection.schema_editor() as schema_editor:
schema_editor.delete_model(self.model)
Run Code Online (Sandbox Code Playgroud)
更新了Django> = 2.0
所以我使用m4rk4l的答案遇到了一些问题:一个是'RuntimeWarning:Model'myapp .__ test__mymodel'已经注册'在其中一个评论中出现的问题,另一个是测试失败,因为该表已经存在.
我添加了一些检查来帮助解决这些问题,现在它可以完美运行.我希望这有助于人们
from django.db import connection
from django.db.models.base import ModelBase
from django.db.utils import OperationalError
from django.test import TestCase
class AbstractModelMixinTestCase(TestCase):
"""
Base class for tests of model mixins/abstract models.
To use, subclass and specify the mixin class variable.
A model using the mixin will be made available in self.model
"""
@classmethod
def setUpTestData(cls):
# Create a dummy model which extends the mixin. A RuntimeWarning will
# occur if the model is registered twice
if not hasattr(cls, 'model'):
cls.model = ModelBase(
'__TestModel__' +
cls.mixin.__name__, (cls.mixin,),
{'__module__': cls.mixin.__module__}
)
# Create the schema for our test model. If the table already exists,
# will pass
try:
with connection.schema_editor() as schema_editor:
schema_editor.create_model(cls.model)
super(AbstractModelMixinTestCase, cls).setUpClass()
except OperationalError:
pass
@classmethod
def tearDownClass(self):
# Delete the schema for the test model. If no table, will pass
try:
with connection.schema_editor() as schema_editor:
schema_editor.delete_model(self.model)
super(AbstractModelMixinTestCase, self).tearDownClass()
except OperationalError:
pass
Run Code Online (Sandbox Code Playgroud)
要使用,请执行与上面相同的方法(现在使用更正缩进):
class MyModelTestCase(AbstractModelMixinTestCase):
"""Test abstract model."""
mixin = MyModel
def setUp(self):
self.model.objects.create(pk=1)
def test_a_thing(self):
mod = self.model.objects.get(pk=1)
Run Code Online (Sandbox Code Playgroud)
我认为你要找的是这样的.
这是链接的完整代码:
from django.test import TestCase
from django.db import connection
from django.core.management.color import no_style
from django.db.models.base import ModelBase
class ModelMixinTestCase(TestCase):
"""
Base class for tests of model mixins. To use, subclass and specify
the mixin class variable. A model using the mixin will be made
available in self.model.
"""
def setUp(self):
# Create a dummy model which extends the mixin
self.model = ModelBase('__TestModel__'+self.mixin.__name__, (self.mixin,),
{'__module__': self.mixin.__module__})
# Create the schema for our test model
self._style = no_style()
sql, _ = connection.creation.sql_create_model(self.model, self._style)
self._cursor = connection.cursor()
for statement in sql:
self._cursor.execute(statement)
def tearDown(self):
# Delete the schema for the test model
sql = connection.creation.sql_destroy_model(self.model, (), self._style)
for statement in sql:
self._cursor.execute(statement)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
5329 次 |
最近记录: |