t.me/atinfo_chat Telegram группа по автоматизации тестирования

Передача параметров из теста в фикстуру для выполнения после завершения теста

fixtures
parameterized
pytest
python
Теги: #<Tag:0x00007f9c549dab00> #<Tag:0x00007f9c549da588> #<Tag:0x00007f9c549da358> #<Tag:0x00007f9c549da088>

(Александр Пикин) #1

Добрый день! Есть необходимость после завершения теста регистрации пользователя удалять только что созданного пользователя. Проблема заключается в том, что функции удаления необходимо передавать логин/пароль для удаления а он генерируется рандомно, и вызвать фикстуру с нужными параметрами у меня не получатся. Подскажите как действовать в таком случае:
фикстура

@pytest.fixture(scope="function")
def delete_user(request, phone, password):
    def delete():
        fixture.sesion.delete_user_interface(password=password, phone=phone, auth=True)
    request.addfinalizer(delete)

тест

user_test5 = User(phone=phone.get_randome_phone(), sms=config.config['USER']['sms_code'], fio='Пикин', email='alpikin63@gmail.com',
                  password='12345', confirm_password='123', data_day='10', data_month='6', data_year='1995',
                  sex='female', approve1=1, approve2=1)

def test_register_correct(app, delete_user):
    with allure.step('Переход на страницу регистрации'):
        app.session.open_rerister_interface()
    with allure.step('заполнение обязательных полей'):
        user = user_test5
        app.session.register(user=user)
    with allure.step('Проверка перехода на страницу Личного кабинета'):
        assert app.wait_by_css(5, app.session.locator_lk_registration_sucsess).is_displayed(), "Регистрация не прошла"
        app.session.open_lk_settings()
    with allure.step('Проверка совпадения данных при регистрации и в личном кабинете'):
        assert app.wait_by_css(5, app.session.locator_lk_settings_name).get_attribute("value") == user.fio
        assert app.wait_by_css(5, app.session.locator_lk_settings_tel).text == '+7 ' + str(user.phone)
        assert app.wait_by_css(5, app.session.locator_lk_settings_email).get_attribute("value") == user.email
    app.session.delete_user_interface(password=user.password, phone=user.phone)

(Vladislav Abramov) #2

ну ведь эти логин и пароль где-то хранятся
тем более вот вы создали пользователя, но не логинитесь им, тест неполный (как по мне)

скорее всего надо в какую-то бд залезть, и там уже цеплять пароль с логином


(Александр Пикин) #3

логин это номер телефона и генерируется рандомно перед началом теста (далее заполняет все поля через интерфейс и регистрируется - после успешной регистрации пользователь авторизуется автоматически) и заранее знать я не могу какой логин, для этого мне и нужно его передать в тердаун!


(Vladislav Abramov) #4

так в чем проблема сгенерированный мобильник сложить заранее в переменную и затем его заюзать в фикстуре?


(Maxim Andryushchenkov) #5

Понимаю вас, вы еще можете столкнуться с массой таких ситуаций и решите это одним способом - сделайте себе тест-менеджер в синглтоне и собирайте в него то, что вам нужно. К примеру:

class PyTestManager:

    delete_user = {}  # Конфигурация юзера для удаления

    def __new__(cls):
        if not hasattr(cls, 'instance'):
            cls.instance = super(PyTestManager, cls).__new__(cls)
        return cls.instance

И далее в тесте заполните delete_user свойство и воспользуйтесь им в фикстуре. Плюс в этом тест-менеджере вы можете заполнить еще кучу полезных переменных.


(Igor Balagurov) #6

Делал такое по следующему принципу:

  1. фикстура сама генерировала рандомного пользователя, хранила его данные и выдавала в тест его.
  2. после теста (после yield) проходимся по массиву пользователей (есть все данные: логины пароли) и удаляем.

выглядит примерно так:

@pytest.fixture(scope="function")
def arrange_user():
    users = []  # здесь храним созданных пользователей в течение теста (кстати можно в таком случае и для сессии\модуля это делать)
    def generate_user(**kwargs):
        user = ...  # тут ваша логика по созданию пользователя. если нужно какого-то специфичного сгенерировать - можно через kwargs пробросить параметры
        users.append(user)
        return user

    yield generate_user  # вместо пользователя возвращается функция для генерации пользователя, но зато можно генерировать несколько и кастомых

  # тут удаляем
    for u in users:
        delete_user(u.login, u.password)

в тесте вызов генерации пользователя выглядит так:

female_user = arrange_user(sex='female')

# можно создавать сколько хочешь и каких хочешь - сами удалятся в конце теста

(Maxim Andryushchenkov) #7

Раньше тоже думал что удаление пользователя после теста - обязательный тирдаун. Ан нет, общался с лидами разных компаний и почти все в один голос говорят - не удаляйте юзера после прохождения теста, особенно после его падения. И решил всегда создавать юзера с определенным префиксом чтобы потом просто почистить базу. В вашей же реализации вы будете чистить всех, даже тех на котором тест упал. Но это уже от проекта зависит наверное.


(Igor Balagurov) #8

По поводу удаления согласен, но это же вопрос одного if - проверил статус теста и удалил если passed. Я отвечал в первую очередь на топик стартер.

Либо ещё мне нравится вариант, когда очищаешь перед прогоном, а не после. Так выглядит даже логичнее - если на том же окружении пытаешься ещё раз запустить тесты, то старые результаты уже не нужны точно.

Можно ключиками при запуске конфигурировать - для временных окружений, которые после тестов удаляются, смысла чистить нет, только время тратить, а для стейдж лайк энвов оставляешь данные от упавших тестов. Но это всё опять же зависит от конкретного проекта, задач, процессов и сложностей в реализации не представляет.


(Maxim Andryushchenkov) #9

Да, такое тоже реализовывал как то. Особенно это актуально для проектов с регистрацией по смс, когда ты не можешь себе позволить много юзеров и удаляешь перед тестом уже имеющегося в базе.