Класс настройки Pytest один раз перед тестированием

Я использую pytest для тестирования с микшерной библиотекой для генерации данных модели. Итак, теперь я пытаюсь настроить свои тесты один раз перед их запуском. Я сгруппировал их в TestClasses, установил область «класса» моих приборов, но это не работает для меня.

      @pytest.mark.django_db
class TestCreateTagModel:

@classmethod
@pytest.fixture(autouse=True, scope='class')
def _set_up(cls, create_model_instance, tag_model, create_fake_instance):
    cls.model = tag_model
    cls.tag = create_model_instance(cls.model)
    cls.fake_instance = create_fake_instance(cls.model)
    print('setup')

def test_create_tag(self, tag_model, create_model_instance, check_instance_exist):
    tag = create_model_instance(tag_model)
    assert check_instance_exist(tag_model, tag.id)

conftest.py

      pytest.fixture(scope='class')
@pytest.mark.django_db(transaction=True)
def create_model_instance():
    instance = None
    def wrapper(model, **fields):
        nonlocal instance
    
        if not fields:
            instance = mixer.blend(model)
        else:
            instance = mixer.blend(model, **fields)  
        return instance

    yield wrapper
    if instance:
        instance.delete()




@pytest.fixture(scope='class')
@pytest.mark.django_db(transaction=True)
def create_fake_instance(create_related_fields):
"""
    Function for creating fake instance of model(fake means that this instance doesn't exists in DB)
    
    Args:
        related (bool, optional): Flag which indicates create related objects or not. Defaults to False.
"""
    instance = None
    def wrapper(model, related=False, **fields):
        with mixer.ctx(commit=False):
            instance = mixer.blend(model, **fields)
         
            if related:
                    create_related_fields(instance, **fields)
            return instance
    
    yield wrapper
    if instance:
        instance.delete()
       

@pytest.fixture(scope='class')
@pytest.mark.django_db(transaction=True)
def create_related_fields():
    django_rel_types = ['ForeignKey']

    def wrapper(instance, **fields):
        for f in instance._meta.get_fields():
            if type(f).__name__ in django_rel_types:
                rel_instance = mixer.blend(f.related_model)

                setattr(instance, f.name, rel_instance)

    return wrapper

Но я ловлю исключение в методе микшера gen_value: доступ к базе данных запрещен, используйте метку django_db(которую я уже использую). У вас есть идеи, как это можно реализовать?

1 ответ

Вы можете настроить все один раз перед запуском, вернув результаты настройки, а не напрямую изменяя класс тестирования. Из моих собственных попыток кажется, что любые изменения в классе, сделанные в рамках классов, теряются при запуске отдельных тестов. Итак, вот как вы должны быть в состоянии сделать это. Замените ваше приспособление _setup на это:

      @pytest.fixture(scope='class')
def model_instance(self, tag_model, create_model_instance):
    return create_model_instance(tag_model)

@pytest.fixture(scope='class')
def fake_instance(self, tag_model, create_fake_instance):
    return create_fake_instance(tag_model)

И затем к ним можно получить доступ через:

      def test_something(self, model_instance, fake_instance):
    # Check that model_instance and fake_instance are as expected

Я сам не знаком с Джанго, так что может быть что-то еще с этим происходит. Это должно помочь вам решить хотя бы одну половину проблемы, если не другую.

Другие вопросы по тегам