【问题标题】:How can I prevent pytest to remove database records between test cases?如何防止 pytest 删除测试用例之间的数据库记录?
【发布时间】:2018-02-12 11:19:05
【问题描述】:

我使用预先创建的 postgres 数据库进行测试。这里是 pytest 设置:
pytest.ini:

[pytest]
norecursedirs = frontend static .svn _build tmp*    
DJANGO_SETTINGS_MODULE = src.settings.testing
addopts = --reuse-db

testing.py:

from .base import *

DEBUG = True

DATABASES = {
    'default': {
        'ENGINE': 'django.contrib.gis.db.backends.postgis',
        'NAME': 'db',
        'USER': 'root',
        'PASSWORD': 'pass',
        'HOST': 'localhost',
        'PORT': '5432',
    }
}

测试夹具:

@pytest.fixture(scope='session')
def user():
    return User.objects.create(name='Test', )

测试用例:

import pytest

pytestmark = pytest.mark.django_db


def test_user(user):
    print(user.pk) # returns pk of newly created user
    print(User.objects.all()) # returns queryset with one user


def test_user2(user):
    print(user.pk) # returns the same value as in the previous test 
    print(User.objects.all()) # returns empty queryset

我无法理解 pytest 设备的行为。每个会话创建一次模型实例,并且在多个测试用例中是相同的。但实际的分贝值是不同的。 Pytest 在第一个测试用例之后删除用户值。
如何防止这种行为并为所有测试会话保存我的数据库记录?

【问题讨论】:

  • 你试过用@pytest.mark.django_db单独装饰测试吗?
  • @YerayDiazDiaz 是的,它的工作方式相同

标签: python django pytest django-testing


【解决方案1】:

这不是--reuse-db 的问题,因为用户在同一个测试运行中从一个测试移到下一个测试。

问题是您将夹具设置为具有session 范围,这意味着夹具将在每次测试运行时执行一次,并且由于 Django 将在测试之间刷新数据库,您的用户实例不再可用为第二次测试。只需从夹具装饰器中删除范围:

@pytest.fixture()
def user():
    return User.objects.create(username='Test')

编辑:来自pytest-django docs“一旦设置,数据库将被缓存以用于所有后续测试并回滚事务以将测试彼此隔离。这是与标准 Django TestCase 使用数据库的方式相同。”

我不明白您为什么要在测试之间使用完全相同的 User 实例,即使您要改变该特定实例,这也意味着测试将相互依赖。为了能够隔离测试,您应该能够按照测试的预期向用户提供。

【讨论】:

  • 但如果我这样做,那么每个测试都会收到不同的用户模型。 scope=session 效果很好,它使用户在测试用例之间保持不变。但用户被缓存在某处,实际的数据库记录又名User.objects.all() 在第一次测试后为空
  • 感谢您的意见。我想我误解了单元测试的核心概念:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-21
  • 2010-12-26
相关资源
最近更新 更多