为什么 Django 实际上不编写测试数据库的更改

Mat*_*ese 2 django

在我的 settings.py 我有这个:

DATABASES = {
    'default': {
    'ENGINE': 'django.db.backends.mysql',
    'NAME': 'foo',
    'USER': 'foo',
    'PASSWORD': 'foo',
    'HOST': 'localhost',
    },
}
Run Code Online (Sandbox Code Playgroud)

我在我的数据库上运行了这个 SQL:

GRANT ALL ON test_foo.* TO 'foo'@'localhost';
Run Code Online (Sandbox Code Playgroud)

我已经通过我的测试提炼了我想要弄清楚的东西:

from django.test import TestCase
from django.contrib.auth.models import User

class UserTestCase(TestCase):

    def test_create_user(self):
        user = User.objects.create_user(
            username='jacob', email='jacob@bla.net', password='top_secret')
        user.save()
        user = User.objects.get(username="jacob")
        import ipdb; ipdb.set_trace()
        self.assertTrue(False)
Run Code Online (Sandbox Code Playgroud)

当我运行测试并遇到断点时,我查询了 test_foo 中的 auth_user 表,它是空的。

为什么是这样?谢谢

Der*_*wok 7

Django 的TestCase类利用数据库事务(如果数据库支持)来加速测试。

这意味着在测试方法中,任何数据库修改仅对该测试可见,不会提交到数据库。您将无法使用外部工具检查更改。

如果您需要测试来提交对测试数据库的更改,您可以TransactionTestCase改为扩展。例如

class UserTestCase(TransactionTestCase):

    def test_create_user(self):
        # any database changes will be visible in the test database
        ....
Run Code Online (Sandbox Code Playgroud)

在每次TransactionTestCase测试结束时,数据库将重置为已知状态。请注意,这会使您的单元测试变慢。再次强调,只有支持事务的数据库(例如 PostgreSQL、MySQL+InnoDB)才会出现这种行为。

有关更多信息,请参阅https://docs.djangoproject.com/en/1.9/topics/testing/tools/#transactiontestcase