如何防止pytest在测试用例之间删除数据库记录?

时间:2017-09-04 08:41:58

标签: python django pytest django-testing

我使用预先创建的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灯具的行为。每个会话创建一次模型实例,在几个测试用例中它是相同的。但实际的db值是不同的。 Pytest在第一个测试用例后删除用户值 如何防止该行为并保留为所有测试会话保存的db记录?

1 个答案:

答案 0 :(得分:1)

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

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

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

编辑:从pytest-django docs“设置完成后,数据库将被缓存以用于所有后续测试,回滚事务以隔离测试。这与标准Django TestCase使用数据库的方式相同。“

我不明白你为什么要在测试之间使用完全相同的User实例,即使你要改变那个特定实例,这意味着测试将依赖于彼此。为了能够隔离测试,您应该能够像测试期望的那样提供用户。