【问题标题】:Django test database is using local db.sqlite3, not running in memoryDjango 测试数据库使用本地 db.sqlite3,不在内存中运行
【发布时间】:2020-05-02 22:18:11
【问题描述】:

当我运行将数据插入数据库的 Django 测试时,它将插入到我的本地 db.sqlite3 并在测试完成时保留它。我不希望这种情况发生,也不应该是according to the docs

无论测试通过还是失败,测试数据库都是 执行完所有测试后销毁。

我的单元测试:

from unittest import TestCase

from web.constants import USER_TYPE_CONTRACTOR
from web.models import User


class LoginTestCase(TestCase):

    def setUp(self):
        self.demo_user_1_username = 'c2'
        User.objects.create(username=self.demo_user_1_username, password='c12345678')

    def test_user_defaults_to_contractor(self):
        demo_user_1 = User.objects.get(username=self.demo_user_1_username)
        self.assertEqual(demo_user_1.user_type, USER_TYPE_CONTRACTOR)

    def doCleanups(self):
        """Delete demo data from database"""
        # I needed to do this as workaround
        # demo_user_1 = User.objects.get(username=self.demo_user_1_username)
        # demo_user_1.delete()

用户c2现在在db.sqlite3中,所以当我再次运行测试时,它失败了,因为用户名c2已经存在。

我已尝试在settings.py 中执行此操作:

DATABASES = {
    'default': dj_database_url.config(conn_max_age=600)
}
DATABASES['default']['TEST'] = {
    'ENGINE': 'django.db.backends.sqlite3',
    'NAME': os.path.join(BASE_DIR, 'test_db.sqlite3'),
}

但是test_db.sqlite3 没有创建。

我如何使用内存中的 sqlite3 数据库,以便在测试时不会影响我的本地数据库?

【问题讨论】:

  • 我不知道这是否是您的问题的原因,但您引用的文档建议在使用数据库访问运行测试时使用 django.test.TestCase 而不是 unittest.TestCase

标签: python django sqlite django-testing django-database


【解决方案1】:

这里的问题,@Chris 是如何从unitetest 模块中直接使用TestCase 时提到的,层次链是这样的:

TestCase->TransactionTestCase->SimpleTestCase->unittest.TestCase

如何documentation总结:

[TestCase] - 这是在 Django 中编写测试最常用的类。它 继承自 TransactionTestCase(并通过扩展 SimpleTestCase)。 如果您的 Django 应用程序不使用数据库,请使用 SimpleTestCase。

这里:

当我运行将数据插入数据库的 Django 测试时,它会 插入到我的本地 db.sqlite3 并在测试完成时保留它。

注意:在您的情况下,测试使用的是实际数据库,这会导致数据丢失和模拟数据填充。 永远不要使用这样的工作流程!

实际上,测试根本不能使用您的实际数据库,默认情况下sqlite3后端Django将处理内存数据库,可以使用标志--keepdb控制数据库的破坏。一般来说,流程如下:

  1. 将使用与实际相同的凭据创建测试数据库 但名称将是test_<actual_db_name>。如果每次测试通过后都没有删除数据库,甚至可以在测试执行之间访问数据库(--keepdb)。
  2. 在测试执行之前,测试数据库将处于实际状态 已执行 python manage.py migrate,但您可以通过覆盖 MIGRATION_MODULES 环境变量来省略迁移执行。

因此,解决方案是改用django.test.TestCase 用法。

【讨论】:

  • 谢谢。使用 from django.test import TestCase 而不是 from unittest import TestCase 效果很好。
猜你喜欢
  • 2011-03-06
  • 2015-01-26
  • 2018-06-27
  • 2020-07-02
  • 1970-01-01
  • 2013-02-20
  • 2022-08-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多