创建临时 Table 用于在 Django 中测试非托管模型
Create Temporary Table For Testing Unmanged Model in Django
我有一个 django 应用程序,它有几个模型,这些模型从非托管数据库中的 tables 读取。
我只是想适当地创建测试以确保应用程序能够尽可能地得到良好测试。我正在使用 factory_boy 来协助创建测试数据。
我的一个非托管模型如下所示:
class EmpGroup(models.Model):
id = models.IntegerField(db_column='id', primary_key=True)
staff_group = models.ForeignKey(
StaffGroup,
db_column='staff_group_id',
on_delete=models.PROTECT
)
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
db_column='user_id',
on_delete=models.PROTECT
)
location = models.ForeignKey(
Location,
db_column='base_loc',
on_delete=models.PROTECT
)
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
location_name = models.CharField(max_length=50)
def __str__(self):
return f'{self.last_name}, {self.first_name}'
class Meta(object):
managed = getattr(settings, 'UNDER_TEST', False)
db_table = 'control_v_empGroup'
因为该模型是非托管的 - 在设置测试数据库时没有迁移告诉它创建 table control_v_empGroup
。所以当我 运行 我的测试时 - 我得到 table 不存在的错误!
我的 EmpGroupFactory 如下所示:
class EmpGroupFactory(factory.django.DjangoModelFactory):
class Meta:
model = models.EmpGroup
id = 1
staff_group = factory.SubFactory(StaffGroupFactory)
user = factory.SubFactory(UserFactory)
location = factory.SubFactory(LocationFactory)
first_name = 'Test'
last_name = 'Grp'
location_name = 'Test'
在我的设置中我有这个:
UNDER_TEST = (len(sys.argv) > 1 and sys.argv[1] == 'test')
if UNDER_TEST:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'default-db.sqlite3'),
},
'camp': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'camp-db.sqlite3'),
},
}
else:
DATABASES =
# actual dbs for regular use
我设置了 UNDER_TEST
以便我可以在测试时将数据库与非文本示例中的常规数据库区分开来。测试数据库是 SQLlite。
有没有办法强制 Django 在测试时为该特定模型设置 table,但在其他时间不设置?
获取非托管模型进行测试的最佳方式是什么?
我最终使用了 Pytest-Django
,因为该测试框架实际上允许做我想做的事情。
使用 --nomigrations
标志,它采用我的模型,这些模型仅由 django 在测试中管理,并在测试数据库中为它们创建适当的 table 名称。然后我可以使用 factory_boy
创建模拟数据并对其进行测试!
我有一个 django 应用程序,它有几个模型,这些模型从非托管数据库中的 tables 读取。
我只是想适当地创建测试以确保应用程序能够尽可能地得到良好测试。我正在使用 factory_boy 来协助创建测试数据。
我的一个非托管模型如下所示:
class EmpGroup(models.Model):
id = models.IntegerField(db_column='id', primary_key=True)
staff_group = models.ForeignKey(
StaffGroup,
db_column='staff_group_id',
on_delete=models.PROTECT
)
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
db_column='user_id',
on_delete=models.PROTECT
)
location = models.ForeignKey(
Location,
db_column='base_loc',
on_delete=models.PROTECT
)
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
location_name = models.CharField(max_length=50)
def __str__(self):
return f'{self.last_name}, {self.first_name}'
class Meta(object):
managed = getattr(settings, 'UNDER_TEST', False)
db_table = 'control_v_empGroup'
因为该模型是非托管的 - 在设置测试数据库时没有迁移告诉它创建 table control_v_empGroup
。所以当我 运行 我的测试时 - 我得到 table 不存在的错误!
我的 EmpGroupFactory 如下所示:
class EmpGroupFactory(factory.django.DjangoModelFactory):
class Meta:
model = models.EmpGroup
id = 1
staff_group = factory.SubFactory(StaffGroupFactory)
user = factory.SubFactory(UserFactory)
location = factory.SubFactory(LocationFactory)
first_name = 'Test'
last_name = 'Grp'
location_name = 'Test'
在我的设置中我有这个:
UNDER_TEST = (len(sys.argv) > 1 and sys.argv[1] == 'test')
if UNDER_TEST:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'default-db.sqlite3'),
},
'camp': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'camp-db.sqlite3'),
},
}
else:
DATABASES =
# actual dbs for regular use
我设置了 UNDER_TEST
以便我可以在测试时将数据库与非文本示例中的常规数据库区分开来。测试数据库是 SQLlite。
有没有办法强制 Django 在测试时为该特定模型设置 table,但在其他时间不设置?
获取非托管模型进行测试的最佳方式是什么?
我最终使用了 Pytest-Django
,因为该测试框架实际上允许做我想做的事情。
使用 --nomigrations
标志,它采用我的模型,这些模型仅由 django 在测试中管理,并在测试数据库中为它们创建适当的 table 名称。然后我可以使用 factory_boy
创建模拟数据并对其进行测试!