Django在运行测试时不创建测试数据库

时间:2021-03-20 17:33:52

标签: django unit-testing automated-tests

我在 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

1 个答案:

答案 0 :(得分:0)

根据文档使用 django.test.TestCase 而不是 unittest.TestCase 有帮助 https://docs.djangoproject.com/en/3.1/topics/testing/overview/

如果您的测试依赖于数据库访问,例如创建或查询模型,请确保将您的测试类创建为 django.test.TestCase 而不是 unittest.TestCase 的子类。 使用 unittest.TestCase 避免了在事务中运行每个测试和刷新数据库的成本,但是如果您的测试与数据库交互,它们的行为将根据测试运行器执行它们的顺序而有所不同。这可能导致单元测试在单独运行时通过但在套件中运行时失败。