Django在运行测试时没有创建测试数据库。

3

我在Django文档中读到,在测试时会创建一个空的数据库。我是Django的新手,所以在setting.py中几乎没有更改,并且目前正在使用Sqlite数据库。然而,当我运行python manage.py test时,Django一直告诉我用户已经存在,因此我尝试在TestCase中为创建的用户更改用户名,再次运行测试,发现新用户被创建在现有的数据库中。下面是测试文件:

class UserTestCase(unittest.TestCase):
    def setUp(self):
        admin = User.objects.create(username="admin", password="1")
        user1 = User.objects.create(username="user1", password="1")
        user2 = User.objects.create(username="user2", password="1")
        admin.following.add(user1)
        admin.followers.add(user2)

    def test_users_count(self):
        self.assertEqual(User.objects.count()==3)

我的模型如下:

class User(AbstractUser):
    followers = models.ManyToManyField('self', related_name="following", symmetrical=False, through='Follow', through_fields=('followee', 'follower'))
    
    def __str__(self):
        return f"{self.username}"

    def serialize(self):
        return {
            "id": self.id,
            "username": self.username,
        }

class Follow(models.Model):
    followee = models.ForeignKey(
        'User',
        on_delete=models.CASCADE,
        related_name='+'
    )
    follower = models.ForeignKey(
        'User',
        on_delete=models.CASCADE,
        related_name='+'
    )

    def clean(self, *args, **kwargs):
        if self.follower__id == self.followee__id:
            raise ValidationError('Can not follow self.')
        return super().clean(*args, **kwargs)
    
    class Meta:
        constraints = [
            models.UniqueConstraint(fields=['follower', 'followee'], name='follow_once'),
            models.CheckConstraint(check=~Q(follower=F('followee')), name='not_follow_self')
        ]

编辑:下面是我运行 python manage.py test 的输出结果:

(env_web) PS C:\Users\HL94NVT\Programming\web_development\project4> python manage.py test
System check identified no issues (0 silenced).
EE
======================================================================
ERROR: test_following_count (network.tests.UserTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Users\HL94NVT\Programming\web_development\env_web\lib\site-packages\django\db\backends\utils.py", line 84, in _execute       
    return self.cursor.execute(sql, params)
  File "C:\Users\HL94NVT\Programming\web_development\env_web\lib\site-packages\django\db\backends\sqlite3\base.py", line 413, in execute
    return Database.Cursor.execute(self, query, params)
sqlite3.IntegrityError: UNIQUE constraint failed: network_user.username

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\HL94NVT\Programming\web_development\project4\network\tests.py", line 21, in setUp
    admin = User.objects.create(username="admin1", password="1")
  File "C:\Users\HL94NVT\Programming\web_development\env_web\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "C:\Users\HL94NVT\Programming\web_development\env_web\lib\site-packages\django\db\models\query.py", line 447, in create
    obj.save(force_insert=True, using=self.db)
  File "C:\Users\HL94NVT\Programming\web_development\env_web\lib\site-packages\django\contrib\auth\base_user.py", line 67, in save
    super().save(*args, **kwargs)
  File "C:\Users\HL94NVT\Programming\web_development\env_web\lib\site-packages\django\db\models\base.py", line 754, in save
    force_update=force_update, update_fields=update_fields)
  File "C:\Users\HL94NVT\Programming\web_development\env_web\lib\site-packages\django\db\models\base.py", line 792, in save_base
    force_update, using, update_fields,
  File "C:\Users\HL94NVT\Programming\web_development\env_web\lib\site-packages\django\db\models\base.py", line 895, in _save_table
    results = self._do_insert(cls._base_manager, using, fields, returning_fields, raw)
  File "C:\Users\HL94NVT\Programming\web_development\env_web\lib\site-packages\django\db\models\base.py", line 935, in _do_insert
    using=using, raw=raw,
  File "C:\Users\HL94NVT\Programming\web_development\env_web\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "C:\Users\HL94NVT\Programming\web_development\env_web\lib\site-packages\django\db\models\query.py", line 1254, in _insert
    return query.get_compiler(using=using).execute_sql(returning_fields)
  File "C:\Users\HL94NVT\Programming\web_development\env_web\lib\site-packages\django\db\models\sql\compiler.py", line 1397, in execute_sql
    cursor.execute(sql, params)
  File "C:\Users\HL94NVT\Programming\web_development\env_web\lib\site-packages\django\db\backends\utils.py", line 66, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "C:\Users\HL94NVT\Programming\web_development\env_web\lib\site-packages\django\db\backends\utils.py", line 75, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "C:\Users\HL94NVT\Programming\web_development\env_web\lib\site-packages\django\db\backends\utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "C:\Users\HL94NVT\Programming\web_development\env_web\lib\site-packages\django\db\utils.py", line 90, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "C:\Users\HL94NVT\Programming\web_development\env_web\lib\site-packages\django\db\backends\utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "C:\Users\HL94NVT\Programming\web_development\env_web\lib\site-packages\django\db\backends\sqlite3\base.py", line 413, in execute
    return Database.Cursor.execute(self, query, params)
django.db.utils.IntegrityError: UNIQUE constraint failed: network_user.username

======================================================================
ERROR: test_users_count (network.tests.UserTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Users\HL94NVT\Programming\web_development\env_web\lib\site-packages\django\db\backends\utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "C:\Users\HL94NVT\Programming\web_development\env_web\lib\site-packages\django\db\backends\sqlite3\base.py", line 413, in execute
    return Database.Cursor.execute(self, query, params)
sqlite3.IntegrityError: UNIQUE constraint failed: network_user.username

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\HL94NVT\Programming\web_development\project4\network\tests.py", line 21, in setUp
    admin = User.objects.create(username="admin1", password="1")
  File "C:\Users\HL94NVT\Programming\web_development\env_web\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "C:\Users\HL94NVT\Programming\web_development\env_web\lib\site-packages\django\db\models\query.py", line 447, in create
    obj.save(force_insert=True, using=self.db)
  File "C:\Users\HL94NVT\Programming\web_development\env_web\lib\site-packages\django\contrib\auth\base_user.py", line 67, in save
    super().save(*args, **kwargs)
  File "C:\Users\HL94NVT\Programming\web_development\env_web\lib\site-packages\django\db\models\base.py", line 754, in save
    force_update=force_update, update_fields=update_fields)
  File "C:\Users\HL94NVT\Programming\web_development\env_web\lib\site-packages\django\db\models\base.py", line 792, in save_base
    force_update, using, update_fields,
  File "C:\Users\HL94NVT\Programming\web_development\env_web\lib\site-packages\django\db\models\base.py", line 895, in _save_table
    results = self._do_insert(cls._base_manager, using, fields, returning_fields, raw)
  File "C:\Users\HL94NVT\Programming\web_development\env_web\lib\site-packages\django\db\models\base.py", line 935, in _do_insert
    using=using, raw=raw,
  File "C:\Users\HL94NVT\Programming\web_development\env_web\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "C:\Users\HL94NVT\Programming\web_development\env_web\lib\site-packages\django\db\models\query.py", line 1254, in _insert
    return query.get_compiler(using=using).execute_sql(returning_fields)
  File "C:\Users\HL94NVT\Programming\web_development\env_web\lib\site-packages\django\db\models\sql\compiler.py", line 1397, in execute_sql
    cursor.execute(sql, params)
  File "C:\Users\HL94NVT\Programming\web_development\env_web\lib\site-packages\django\db\backends\utils.py", line 66, in execute
    return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
  File "C:\Users\HL94NVT\Programming\web_development\env_web\lib\site-packages\django\db\backends\utils.py", line 75, in _execute_with_wrappers
    return executor(sql, params, many, context)
  File "C:\Users\HL94NVT\Programming\web_development\env_web\lib\site-packages\django\db\backends\utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "C:\Users\HL94NVT\Programming\web_development\env_web\lib\site-packages\django\db\utils.py", line 90, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "C:\Users\HL94NVT\Programming\web_development\env_web\lib\site-packages\django\db\backends\utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "C:\Users\HL94NVT\Programming\web_development\env_web\lib\site-packages\django\db\backends\sqlite3\base.py", line 413, in execute
    return Database.Cursor.execute(self, query, params)
django.db.utils.IntegrityError: UNIQUE constraint failed: network_user.username

----------------------------------------------------------------------
Ran 2 tests in 0.063s

你可以展示一下 python manage.py test 的输出吗? - 2293980990
我编辑了问题并添加了输出。 - UMR
1
我能想到的唯一一件事是你没有使用 Django 的 TestCase 来运行测试,这是必须的,以便原子性地运行测试,但我不确定这是否会导致数据库无法创建。建议尝试使用 from django.test import TestCase。如果这样不行,请运行 python manage.py test -v 3 并发布您的设置文件(如果您打算部署此应用程序,请确保隐藏敏感信息)。 - 2293980990
从unittest.TestCase更改为django.test.TestCase解决了这个问题。 - UMR
1个回答

4

根据文档https://docs.djangoproject.com/en/3.1/topics/testing/overview/,如果您的测试依赖于数据库访问(例如创建或查询模型),请确保将测试类创建为django.test.TestCase的子类,而不是unittest.TestCase。

使用django.test.TestCase代替unittest.TestCase可以帮助减少运行每个测试时的事务成本和刷新数据库。但是,如果您的测试与数据库交互,则它们的行为将基于测试运行程序执行它们的顺序而变化。这可能会导致单元测试在独立运行时通过,但在套件运行时失败。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接