Django Web Framework/Django Pytest

@pytest.mark.django_db 와 db fixture, db 사용 법의 모든것

bluebamus 2023. 4. 2.

- DB 연결 테스트

별도 테스트 DB 설정

# settings.py

# Default database configuration
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'mydatabase',
        'USER': 'mydatabaseuser',
        'PASSWORD': 'mypassword',
        'HOST': 'localhost',
        'PORT': '5432',
    }
}

# Database configuration for testing
DATABASES['test'] = {
    'ENGINE': 'django.db.backends.postgresql',
    'NAME': 'mytestdatabase',
    'USER': 'mytestdatabaseuser',
    'PASSWORD': 'mytestpassword',
    'HOST': 'localhost',
    'PORT': '5432',
}

test db 선택

pytest --database=test

 

 

# settings.py에 DATABASES 설정

"default": {
        "ENGINE": "django.db.backends.mysql",
        "HOST": config("DEFAULT_DB_HOST"),
        "PORT": config("DEFAULT_DB_PORT", default=3306, cast=int),
        "NAME": config("DEFAULT_DB_NAME"),
        "USER": config("DEFAULT_DB_USER"),
        "PASSWORD": config("DEFAULT_DB_PASSWORD"),
        "CHARSET": config("DEFAULT_DB_CHARSET"),
        "TEST": {
            "ENGINE": "django.db.backends.sqlite3",
            "NAME": BASE_DIR / "test_default.sqlite3",
        },
        # * 주의 TEST 파라미터는 데이터베이스 사용후 삭제함
    },

   - db를 인수로 받는 경우는 실존하는 db를 사용, default의 mysql 연결, 기본 설정으로 데이터 초기화 안함 (옵션에 따라 상이)

# conftest.py

@pytest.fixture(scope="function")
def sample_model(db):
    sample = SampleModel.objects.create(name="Sample")
    return sample

# test_sample.py

def test_sample_model(sample_model):
    assert SampleModel.objects.count() == 1

   - @pytest.mark.django_db 사용시 테스트 서버를 사용하고 사용한 뒤 데이터 초기화를 함 (옵션에 따라 상이)

   - "TEST" 선언 항목 사용

   - chatGPT 정리 

      - Pytest의 가장 강력한 기능 중 하나는 픽스처 지원입니다. 고정 장치는 데이터베이스 연결 또는 웹 서버 인스턴스와            같이 테스트에 필요한 리소스를 설정하고 해제하는 데 사용할 수 있는 재사용 가능한 코드 블록입니다.
      -Django 애플리케이션용 테스트를 작성할 때 @pytest.mark.django_db 데코레이터를 사용하여 테스트용 테스트 

       데이터베이스를 자동으로 설정할 수 있습니다. 이 데코레이터는 Pytest에게 이를 사용하는 각 테스트 함수에 대해

       새 테스트 데이터베이스를 만들고 테스트가 완료된 후 이 데이터베이스를 정리하도록 지시합니다.
      - @pytest.mark.django_db를 사용하면 테스트 데이터베이스를 수동으로 설정하고 해체하는 것에 대해 걱정할 필요가

       없으므로 Django 애플리케이션에 대한 테스트를 훨씬 쉽게 작성할 수 있습니다. 또한 각 테스트가 깨끗하고 격리된

       환경에서 실행되도록 하여 테스트 간의 간섭을 방지합니다.

 

# conftest.py

@pytest.fixture(scope="function")
def sample_model(django_db_setup, django_db_blocker):
    with django_db_blocker.unblock():
        sample = SampleModel.objects.create(name="Sample")
    return sample

# test_sample.py

@pytest.mark.django_db
def test_sample_model(sample_model):
    assert SampleModel.objects.count() == 1

- pytest.mark.django_db 테스트 (chatGPT)

   - 결과 첫번째 결과 = 1, 두번째 결과 = 0, 이유는 매 테스트 함수별 db는 초기화 된다.

import pytest
from django.contrib.auth.models import User

@pytest.mark.django_db
def test_user_create():
    User.objects.create_user('test','test@test.com','test')
    count = User.objects.all().count()
    print(count)
    assert User.objects.count() == 1


@pytest.mark.django_db
def test_user_create1():    
    count = User.objects.all().count()    
    print(count)
    assert User.objects.count() == 0

   

- db 인수 테스트(chatGPT)

   - "default" 선언 항목 사

   - chatGPT 정리 

      - @pytest.mark.django_db는 강력한 도구이지만 테스트 요구에 항상 최선의 선택은 아닙니다. 경우에 따라 테스트 

        데이터베이스를 보다 세밀하게 제어하거나 기존 데이터베이스 인스턴스에 대해 테스트를 실행할 수 있습니다.
      - 이러한 경우 Pytest에서 db 매개변수를 사용하여 테스트 데이터베이스를 수동으로 설정할 수 있습니다. 이 매개변수

        를 사용하면 사용할 테스트 데이터베이스의 이름과 데이터베이스 엔진 및 사용자 자격 증명과 같은 기타 옵션을 지정

        할 수 있습니다.
      -  db 매개변수를 사용하면 테스트 데이터베이스를 더 많이 제어해야 하거나 @pytest.mark.django_db를 사용하여

        복제할 수 없는 특정 데이터베이스 구성에 대해 테스트하려는 경우에 유용할 수 있습니다.

import pytest
from django.contrib.auth.models import User

@pytest.fixture()
def user_1(db):
    user = User.objects.create_user("test-user")
    return user


def test_set_check_password_true(user_1):    
    assert user_1.username == "test-user"

   - pytest.mark.django_db, db 파라미터 두 방법간 사용에 대한 정리(chatGPT)

   - chatGPT 정리

      - Django 애플리케이션 테스트를 막 시작했거나 상대적으로 간단한 테스트 스위트가 있는 경우 

        @pytest.mark.django_db가 최선의 선택일 가능성이 높습니다. 이 옵션은 설정하기 쉽고 테스트 간에 적절한 수준의

        격리를 제공하므로 대부분의 애플리케이션에 적합합니다.
      - 더 복잡한 테스트 스위트가 있거나 대규모 데이터베이스를 다루는 경우 대신 db 매개변수를 사용하는 것이 좋습니다.

        이 옵션을 사용하면 데이터베이스 구성을 보다 세밀하게 제어할 수 있으므로 성능 및 정확성을 위해 테스트를 최적화

        할 수 있습니다.
      - 일반적으로 @pytest.mark.django_db로 시작하고 특정 문제가 발생하는 경우에만 db 매개변수로 전환하는 것이

        좋습니다.

 

   - 추가 정리 

      - pytest-django의 db 고정 장치와 django_db 고정 장치는 모두 테스트 함수에 대한 데이터베이스 연결을 

       제공하지만 이들 사이에는 몇 가지 중요한 차이점이 있습니다.

      - db 픽스처는 pytest에서 제공하는 범용 픽스처로 각 테스트 기능에 대한 트랜잭션 데이터베이스 

       연결을 제공합니다. 이 픽스처는 SQLAlchemy에서 지원하는 모든 데이터베이스 백엔드와 함께 사용할 수

       있으며 Django뿐만 아니라 모든 Python 애플리케이션에 대한 테스트를 작성하는 데 사용할 수 있습니다.

      - 반면에 django_db 고정 장치는 Django 애플리케이션 테스트용으로 특별히 설계되었으며 Django 자체 

        데이터베이스 구성을 사용하여 데이터베이스 연결을 제공합니다. 이 픽스처는 Django가 지원하는 모든

        데이터베이스 백엔드를 지원하고 Django의 강력한 ORM 및 쿼리 기능에 대한 액세스를 제공합니다.

      - 두 고정 장치의 주요 차이점은 Django와의 통합 수준입니다. db 고정 장치는 모든 데이터베이스 

        백엔드에서 사용할 수 있는 보다 범용적인 고정 장치인 반면 django_db 고정 장치는 Django와 긴밀하게

        통합되어 Django의 ORM 및 쿼리 기능에 대한 액세스를 제공합니다.

      - 일반적으로 Django 애플리케이션을 테스트하는 경우 Django ORM의 모든 기능에 대한 액세스를 

        제공하는 django_db 고정 장치를 사용하는 것이 좋습니다. 그러나 비 Django 애플리케이션에 대한 테스트를

        작성하거나 Django에서 지원하지 않는 데이터베이스 백엔드와의 상호 작용을 테스트해야 하는 경우 대신

        db 고정 장치를 사용할 수 있습니다.

      - 두 픽스처 모두 테스트 기능이 완료된 후 자동으로 롤백되는 각 테스트 기능에 대한 트랜잭션 데이터베이스 

        연결을 제공한다는 점에 유의하는 것이 중요합니다. 이렇게 하면 각 테스트 기능이 깨끗한 데이터베이스에서

        작동하고 수동 데이터베이스 설정 및 분해 로직이 필요하지 않습니다.

 

    * 설명이 부족해서 한참의 대화를 한 결과 다음과 같은 결론을 얻음

DATABASES={
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'mydatabase',
        'USER': 'mydatabaseuser',
        'PASSWORD': 'mypassword',
        'HOST': 'localhost',
        'PORT': '5432',
        "TEST": {
            "ENGINE": "django.db.backends.sqlite3",
            "NAME":BASE_DIR/"test_default.sqlite3",
        },
    },
}

   - 위와 같은 설정이 되어 있을 때, pytest.mark.django_db는 'TEST'에 선언된 "ENGINE": "django.db.backends.sqlite3"를 사용하고 초기화 한다.

   - db 픽스처는 'default'에 선언된 "ENGINE': 'django.db.backends.postgresql',를 사용하고 롤백한다. 즉 이전 상태로 원상복구를 시킨다.

import pytest
from myapp.models import MyModel
from pytest_django.plugin import db_helpers


@pytest.fixture(scope='session')
def django_db_setup():
    # Setup the test database before running tests
    from django.core.management import call_command
    call_command('migrate')


@pytest.fixture
def db_blocker(request):
    # Setup a database blocker to prevent transactions from committing
    with db_helpers.disable_transaction_methods():
        yield


def test_model_creation(db, db_blocker):
    # We can use the db fixture to interact with the test database
    # Use the db_blocker fixture to prevent transactions from committing
    with db_blocker():
        with db.atomic():
            MyModel.objects.create(name="Test Model")
    assert MyModel.objects.count() == 1

   - 위 코드에서 사용한 with db_helpers.disable_transaction_methods(): 라인은 트랜잭션이 커밋되지 않도록 데이터베이스 blocker를 설정합니다.

   - 그리고 with db.atomic():을 사용하여 모델 생성이 데이터베이스에 커밋되고 후속 테스트에 사용할 수 있도록 합니다.

 

import pytest
from django.test import TransactionTestCase

@pytest.fixture(scope='function')
def django_db_setup(django_db_blocker):
    with django_db_blocker.unblock():
        TransactionTestCase().setUpClass()
    yield
    with django_db_blocker.unblock():
        TransactionTestCase().tearDownClass()

@pytest.fixture(scope='function')
def db(request, django_db_setup, django_db_blocker):
    with django_db_blocker.unblock():
        request.cls.db = TransactionTestCase.multi_db and \
            dict((alias, TransactionTestCase.databases.get(alias, {}).get('NAME'))
                 for alias in TransactionTestCase.multi_db) or \
            TransactionTestCase.databases.get('default', {}).get('NAME')
        request.cls.live_server_url = None
    yield

   - 이 업데이트된 코드에서는 Django의 django.test 모듈에서 TransactionTestCase 클래스를 가져왔습니다. 

     우리는 이 클래스를 사용하여 django_db_setup fixture에서 데이터베이스를 설정하고 해제합니다. db fixture는

     변경되지 않으며 django_db_setup fixture를 사용하여 각 테스트에 대한 데이터베이스를 설정합니다.

     django_db_blocker fixture도 변경되지 않으며 db fixture 외부에서 데이터베이스를 수정하려는 시도를 차단하는 데 사용

     됩니다.

 

   - @pytest.fixture(scope='function'): 각 테스트 함수에 범위가 지정된 고정 장치를 정의합니다.
   - def django_db_setup(django_db_blocker): fixture를 선언하고 django_db_blocker fixture를 주입합니다.
   - with django_db_blocker.unblock():: Django 데이터베이스 액세스 차단을 일시적으로 비활성화합니다.
   - TransactionTestCase().setUpClass(): 현재 스레드에 대한 테스트 데이터베이스를 설정하는 TransactionTestCase

     의 setUpClass 메서드를 호출합니다.
   - yield: 테스트 기능을 실행할 수 있습니다.
   - with django_db_blocker.unblock():: Django 데이터베이스 액세스 차단을 일시적으로 비활성화합니다.
   - TransactionTestCase().tearDownClass(): TransactionTestCase의 tearDownClass 메서드를 호출하여 현재 스레드에 

     대한 테스트 데이터베이스를 해제합니다.

 

- django_db_setup, django_db_blocker에 대한 정리(chatGPT)

   - django_db_setup 및 django_db_blocker는 Django 테스트에서 데이터베이스 설정 및 분해를 관리하기 위해

     pytest-django 플러그인에서 제공하는 고정 장치입니다.
   - django_db_setup은 현재 테스트 기능에서 사용할 테스트 데이터베이스를 설정하는 고정 장치입니다. 테스트 데이터베

     이스가 필요한 스키마 및 고정 장치로 올바르게 초기화되었는지 확인합니다. 이 픽스처는 @pytest.mark.django_db

     데코레이터가 테스트 함수에 적용될 때 자동으로 사용됩니다.
   - django_db_blocker는 Django 데이터베이스에 대한 액세스를 차단하기 위한 컨텍스트 관리자를 제공하는 고정 장치입

     니다. 이를 통해 테스트 설정 또는 해제 중에 데이터베이스 액세스를 일시적으로 비활성화할 수 있으며, 이는 데이터베

     이스 액세스가 필요하지 않은 작업을 수행할 때 유용할 수 있습니다.

 

- 다음은 Django 테스트에서 이러한 고정 장치를 사용하는 방법의 예입니다.

import pytest
from django.contrib.auth.models import User

@pytest.fixture(scope='function')
def user_db(django_db_setup, django_db_blocker):
    with django_db_blocker.unblock():
        # create a user
        user = User.objects.create_user('testuser', 'test@example.com', 'password')
        yield user
        # teardown - delete the user
        user.delete()

@pytest.mark.django_db
def test_user_creation(user_db):
    # assertion - check that the user was created successfully
    assert user_db.username == 'testuser'

   - 이 예에서 user_db 픽스처는 User.objects.create_user()를 사용하여 데이터베이스에 테스트 사용자를 생성하고 테스트

     에 사용할 사용자 개체를 생성합니다. django_db_blocker 고정 장치는 사용자 생성 및 삭제 중에 데이터베이스 액세스

    차단을 해제하는 데 사용됩니다.
   - @pytest.mark.django_db 데코레이터는 테스트 기능 중에 데이터베이스 액세스를 활성화하는 데 사용됩니다. 테스트

    기능이 완료되면 user 개체는 픽스처의 분해 코드에 의해 테스트 데이터베이스에서 자동으로 삭제됩니다.
   - 전반적으로 django_db_setup 및 django_db_blocker는 Django 테스트에서 데이터베이스 액세스를 관리하는 데 유용한

    고정 장치로 프로덕션 데이터베이스에 영향을 주지 않고 테스트 데이터를 쉽게 만들고 조작할 수 있습니다.

 

- 더 상세한 이해를 위한 가상 시나리오 기반 예시 코드(chatGPT)

 

django_db_blocker 예시

예제 1: 동시 데이터베이스 트랜잭션 테스트

이 시나리오에서는 동시 데이터베이스 트랜잭션을 테스트하고 서로 간섭하지 않는지 확인하려고 합니다. 두 개의 django_db_blocker 고정 장치를 사용하여 각 트랜잭션이 서로 간섭하지 않도록 차단합니다.

import pytest
from myapp.models import MyModel

@pytest.fixture(scope='function')
def transaction_blocker_1(django_db_blocker):
    with django_db_blocker.unblock():
        yield

@pytest.fixture(scope='function')
def transaction_blocker_2(django_db_blocker):
    with django_db_blocker.unblock():
        yield

@pytest.mark.django_db
def test_concurrent_transactions(transaction_blocker_1, transaction_blocker_2):
    with transaction_blocker_1:
        # perform some database operation
        MyModel.objects.create(name="Test Model 1")
    with transaction_blocker_2:
        # perform another database operation
        MyModel.objects.create(name="Test Model 2")

    assert MyModel.objects.count() == 2

예제 2: 데이터베이스 롤백 테스트

이 시나리오에서는 예외가 발생할 때 함수 내의 데이터베이스 작업이 롤백되는지 테스트하려고 합니다. 데이터베이스 작업이 제대로 롤백되도록 두 개의 django_db_blocker 고정 장치를 사용합니다.

import pytest
from myapp.models import MyModel

@pytest.fixture(scope='function')
def db_operation_blocker(django_db_blocker):
    with django_db_blocker.unblock():
        yield

@pytest.mark.django_db
def test_database_rollback(db_operation_blocker):
    with db_operation_blocker:
        # perform some database operation
        MyModel.objects.create(name="Test Model")
        assert MyModel.objects.count() == 1

        # raise an exception to trigger a rollback
        raise Exception()

    # make sure the database operation was rolled back
    assert MyModel.objects.count() == 0

django_db_setup 예시

예제 1: 여러 필드가 있는 모델 테스트

first_name, last_name 및 age와 같은 여러 필드가 있는 Person이라는 Django 모델이 있다고 가정합니다. 우리는 Person의 여러 인스턴스를 생성하고 올바르게 저장되었는지 확인하는 테스트를 작성하려고 합니다. django_db_setup을 사용하여 테스트 데이터베이스를 설정하고 django_db_blocker를 사용하여 테스트 중에 데이터베이스 트랜잭션을 비활성화할 수 있습니다.

import pytest
from myapp.models import Person

@pytest.fixture(scope='function')
def django_db_setup(django_db_blocker):
    with django_db_blocker.unblock():
        TransactionTestCase().setUpClass()
    yield
    with django_db_blocker.unblock():
        TransactionTestCase().tearDownClass()

@pytest.fixture(scope='function')
def people():
    with django_db_blocker.unblock():
        person1 = Person.objects.create(first_name='John', last_name='Doe', age=25)
        person2 = Person.objects.create(first_name='Jane', last_name='Smith', age=30)
        yield [person1, person2]

@pytest.mark.django_db
def test_people_creation(people):
    assert people[0].first_name == 'John'
    assert people[0].last_name == 'Doe'
    assert people[0].age == 25
    assert people[1].first_name == 'Jane'
    assert people[1].last_name == 'Smith'
    assert people[1].age == 30

이 예제에서는 django_db_setup을 사용하여 테스트 데이터베이스를 설정하고 django_db_blocker를 사용하여 Person 인스턴스를 생성하는 동안 데이터베이스 트랜잭션을 비활성화합니다. people 고정물은 Person의 두 인스턴스를 생성하고 목록으로 생성합니다. 테스트 기능에서 각 인스턴스의 데이터가 올바르게 저장되었는지 확인합니다.

 

예 2: 사용자 인증 테스트

사용자 인증이 필요한 Django 애플리케이션이 있다고 가정합니다. 사용자가 성공적으로 로그인할 수 있는지 확인하는 테스트를 작성하려고 합니다. django_db_setup을 사용하여 테스트 데이터베이스를 설정하고 django_db_blocker를 사용하여 테스트 중에 데이터베이스 트랜잭션을 비활성화할 수 있습니다.

import pytest
from django.contrib.auth import authenticate, get_user_model

User = get_user_model()

@pytest.fixture(scope='function')
def django_db_setup(django_db_blocker):
    with django_db_blocker.unblock():
        TransactionTestCase().setUpClass()
    yield
    with django_db_blocker.unblock():
        TransactionTestCase().tearDownClass()

@pytest.fixture(scope='function')
def user():
    with django_db_blocker.unblock():
        user = User.objects.create_user(username='testuser', email='test@example.com', password='testpassword')
        yield user

@pytest.mark.django_db
def test_user_authentication(user):
    authenticated_user = authenticate(username='testuser', password='testpassword')
    assert authenticated_user == user

이 예제에서는 django_db_setup을 사용하여 테스트 데이터베이스를 설정하고 django_db_blocker를 사용하여 User 인스턴스를 생성하는 동안 데이터베이스 트랜잭션을 비활성화합니다. user 픽스처는 User 인스턴스를 생성하고 생성합니다. test 함수에서 authenticate 함수를 사용하여 사용자가 성공적으로 로그인할 수 있는지 확인하고 반환된 사용자가 fixture에서 생성된 사용자와 동일하다고 주장합니다.

 

예 3: 여러 데이터베이스 동기화 테스트

여러 데이터베이스를 사용하는 Django 애플리케이션이 있고 데이터베이스 간에 데이터가 성공적으로 동기화될 수 있는지 확인하는 테스트를 실행하려고 한다고 가정합니다. 테스트가 올바른 데이터베이스에 대해 실행되고 데이터베이스가 테스트 전후에 일관된 상태인지 확인하려고 합니다. 다음은 이 시나리오에서 django_db_setup 고정 장치를 사용하는 방법의 예입니다.

import pytest
from myapp.models import MyModel

@pytest.fixture(scope='function')
def my_model_db_setup(django_db_setup, django_db_blocker):
    with django_db_blocker.unblock():
        # Here you can define any setup logic that you need for your test
        MyModel.objects.using('database1').create(name='Test Model')
        MyModel.objects.using('database2').create(name='Test Model')
        yield
        # Here you can define any teardown logic that you need for your test
        MyModel.objects.using('database1').all().delete()
        MyModel.objects.using('database2').all().delete()

@pytest.mark.django_db
def test_my_model_sync(my_model_db_setup):
    # Here you can write your test code that relies on the databases
    MyModel.objects.using('database1').all().update(name='Test Model Updated')
    assert MyModel.objects.using('database2').filter(name='Test Model Updated').exists()

이 예제에서는 django_db_setup 및 django_db_blocker에 의존하는 my_model_db_setup 고정 장치를 사용하여 두 개의 데이터베이스(database1 및 database2)와 각각의 MyModel 모델 인스턴스를 설정하고 해제합니다. 테스트 코드는 database1에서 모델 인스턴스의 이름을 업데이트하고 업데이트된 이름이 database2와 올바르게 동기화되었는지 확인합니다.

 

db fixture를 사용할 경우 'TEST' db를 사용하게 설정하는 방법

"default": {
        "ENGINE": "django.db.backends.mysql",
        "HOST": config("DEFAULT_DB_HOST"),
        "PORT": config("DEFAULT_DB_PORT", default=3306, cast=int),
        "NAME": config("DEFAULT_DB_NAME"),
        "USER": config("DEFAULT_DB_USER"),
        "PASSWORD": config("DEFAULT_DB_PASSWORD"),
        "CHARSET": config("DEFAULT_DB_CHARSET"),
        "TEST": {
            "ENGINE": "django.db.backends.sqlite3",
            "NAME": BASE_DIR / "test_default.sqlite3",
        },
        # * 주의 TEST 파라미터는 데이터베이스 사용후 삭제함
    },
import pytest
from django.conf import settings
from django.test import TransactionTestCase
from pytest_django.plugin import _blocking_manager, _DatabaseBlocker

@pytest.fixture(scope='function')
def django_db_setup(django_db_blocker):
    with django_db_blocker.unblock():
        TransactionTestCase().setUpClass()
    yield
    with django_db_blocker.unblock():
        TransactionTestCase().tearDownClass()

@pytest.fixture(scope='session')
def django_db_modify_db_settings():
    # modify the DATABASES setting to use the TEST database
    databases = settings.DATABASES.copy()
    databases['default']['NAME'] = databases['default']['TEST']['NAME']
    settings.DATABASES = databases

@pytest.fixture(scope='function')
def db(request, django_db_blocker, django_db_modify_db_settings):
    # unblock the database and modify the settings to use the TEST database
    django_db_blocker.unblock()
    _blocking_manager.unblock()
    request.addfinalizer(lambda: _blocking_manager.block())
    request.addfinalizer(lambda: django_db_blocker.block())
    yield
    # block the database and restore the original settings
    _blocking_manager.block()
    django_db_blocker.block()
    databases = settings.DATABASES.copy()
    databases['default'].update(databases['default']['TEST'])
    settings.DATABASES = databases

_blocking_manager는 데이터베이스에 대한 액세스를 차단 및 차단 해제하는 데 사용되는 pytest_django.plugin 모듈의 비공개 속성입니다. 위의 코드에는 정의되어 있지 않지만 _blocking_manager 속성을 통해 pytest_django.plugin 모듈을 통해 액세스합니다.

 

django_db_blocker를 사용할 때 _blocking_manager는 pytest-django에서 내부적으로 사용되어 테스트 설정 및 해제 중에 데이터베이스 액세스 차단 및 차단 해제를 관리합니다. 따라서 테스트 코드에서 직접 _blocking_manager를 정의하거나 액세스할 필요가 없습니다.

* 위에 작성된 대부분의 코드 중 간단한 것들은 동작이 될 것이 이해가 되지만, 복잡한 코드들은 동작 결과에 보장을 할 수 없을것 같다. 테스트가 필요함 

* 문제가 있을법한 코드를 기록한 이유는, 비슷한 질문을 여러번 한 결과 비슷한 결과를 얻었기 때문에 높은 신뢰성을 가지게 되었고, 차후 이 자료로 재 질문을 통해 더 확실하고 깊은 코드의 결과를 얻어낼 수 있을거라 생각되기 때문이다.

 

 

reference:

https://uiandwe.tistory.com/1342

 

pytest 시 여러개의 디비 사용하기

참고로 pytest-django 에서 여러개의 디비를 사용하도록 하는 공식적인 버전은 4.3.0 부터 입니다. 해당 버전이 아닐경우 다른 결과가 나올수 있습니다. 1. 테스트 격리! 일단 나의 진행중인 프로젝트

uiandwe.tistory.com

https://rumbarum.github.io/posts/pytest-django-db-setup/

 

pytest-django TEST DB setup - 개발세발개발

1. Test DB 생성 (django default) 및 이용 settings.DATABASES config 활용 test_ DB schema 생성 django models 바탕으로 DB 생성 Test data: 비어 있는 TEST DB 에 실행하기 원하는 데이터를 채워넣어줘야 한다. models.py 에서

rumbarum.github.io

https://jadehan.tistory.com/4

 

단위 테스트 pytest-django 튜토리얼 - [1]

해당 포스트는 Django Framework 에 대한 기초적인 지식을 필요로한다. 아래의 링크를 통해 튜토리얼의 소스코드를 clone 할 수 있다. https://github.com/deadlylaid/testing 단위테스트란 무엇인가? 단위테스트

jadehan.tistory.com

https://www.velotio.com/engineering-blog/use-pytest-fixtures-with-django-models

 

How to Use Pytest Fixtures With Django Models

Learn how to provide test fixtures for your Django models using Pytest and write easy-to-read tests for your app.

www.velotio.com

https://pytest-django.readthedocs.io/en/latest/database.html

 

Database access — pytest-django documentation

Warning It does not manage transactions and changes made to the database will not be automatically restored. Using the pytest.mark.django_db marker or db fixture, which wraps database changes in a transaction and restores the state is generally the thing y

pytest-django.readthedocs.io

https://pytest-django.readthedocs.io/en/latest/helpers.html

 

Django helpers — pytest-django documentation

Note If you want access to the Django database inside a fixture, this marker may or may not help even if the function requesting your fixture has this marker applied, depending on pytest’s fixture execution order. To access the database in a fixture, it

pytest-django.readthedocs.io

 

댓글