Перейти к содержимому

Фотография

Передача результата функции с параметром request в фикстуру (pytest)

selenium webdriver python pytest fixtures

  • Авторизуйтесь для ответа в теме
Сообщений в теме: 5

#1 Kristall89

Kristall89

    Новый участник

  • Members
  • Pip
  • 10 сообщений


Отправлено 03 февраля 2024 - 20:25

Привет. Вопрос скорее по питону, чем по собственно тестированию, но возник в процессе написания автотестов.

 

Есть проект с несколькими типами аккаунтов (пользователь и разные виды магазинов). Для тестирования страниц профиля, онлайн-заказа и тд работаю над фикстурой, которая в начале теста выполняет авторизацию, а в конце разлогинивается.

Файл с логинами-паролями выглядит как на скрине (сложный словарь):

f64bb6d9075c7ea440c7b92c3e1eb01b2300ce00

 

Сразу уточняю: я в курсе, что это не безопасно, но аккаунты типовые без каких-либо данных и дополнительных прав. Если кто-то получит к ним доступ, то узнает не больше, чем если зарегистрируется сам))))

 

В текущем варианте есть две одинаковых фикстуры, отдельно для юзеров (которых потом будет несколько) и для продавцов. В каждую фикстуру в виде параметра передается соответствующая часть словаря. И есть два очень похожих набора тестов, часть из которых отличаются только названиями и тем, какая фикстура в них передается.

Мне такое решение не нравится количеством кода и сложностью поддержки как минимум, ну и просто криво.

 

Такой код в старом варианте:

@pytest.fixture(scope="function", params=Accounts.VENDORS.values())   #быстрая авторизация для профиля вендора (перебор всех вендоров)
def log_in_vendor(server_name, request, browser):
    link = f"{server_name}{links.LOG_IN_WITH_EMAIL}"
    email, password = request.param.values()
    page = EmailLoginPage(browser, link)
    page.open()
    page.print_text_to_field(EmailLoginPageLocators.LOGIN_INPUT_EMAIL, email)
    page.print_text_to_field(EmailLoginPageLocators.LOGIN_INPUT_PASS, password)
    page.click_to_login_button()
    current_url = browser.current_url
    WebDriverWait(browser, 15).until(EC.url_changes(current_url))
    yield log_in_vendor
    print(f"\n{email}")
    page.logout()

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

Функция сейчас выглядит так:

def user_accounts(request):
    users = request.config.getoption("-m")
    if users == "ind_user":
        user_accounts = Accounts.USERS.values()
    elif users == "vendor":
        user_accounts = Accounts.VENDORS.values()
    else:
        user_accounts = dict(Accounts.USERS.values()).update(Accounts.VENDORS.values())
    print(user_accounts)
    return user_accounts

Проблема: при попытке вызывать эту функцию в params интерпретатор пишет ошибку - не указан 1 обязательный параметр (т.к. функция получает данные из командной строки, ей нужен параметр request). Гугл говорит, что чтобы сделать параметр необязательным, нужно задать ему значение по умолчанию, но я не понимаю, какое в этой ситуации можно указать значение (или что передать в вызов в качестве параметра).

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

(Вариант "это говнокод, все надо делать совсем иначе" принимается при наличии объяснений, как именно иначе и почему так лучше)

 


  • 0

#2 alexbol93

alexbol93

    Новый участник

  • Members
  • Pip
  • 2 сообщений

Отправлено 05 февраля 2024 - 19:45

Кажется: в этой статье вы найдете ответы
https://www.software...-line-arguments
 


  • 0

#3 Kristall89

Kristall89

    Новый участник

  • Members
  • Pip
  • 10 сообщений


Отправлено 05 февраля 2024 - 20:20

Кажется: в этой статье вы найдете ответы
https://www.software...-line-arguments
 

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

А тут задача передать список аккаунтов не в функцию, а именно в параметры фикстуры, вот сюда (нужное место выделено подчеркиваниями):

@pytest.fixture(scope="function", _____params=user_accounts()_____)   #быстрая авторизация для профиля юзера (перебор всех юзеров)
def log_in_user(server_name, browser, request):

чтобы тест отработал с каждым из аккаунтов в списке отдельно.

Ну или я чего-то не понимаю и это надо делать вообще по-другому)))

Конечная задача - формировать список аккаунтов, на которых будет запущен тест, исходя из соответствующего параметра командной строки.


  • 0

#4 alexbol93

alexbol93

    Новый участник

  • Members
  • Pip
  • 2 сообщений

Отправлено 06 февраля 2024 - 12:51

Если я вас правильно понял, можете попробовать что-то подобное

https://gist.github....f900b5c7abde853


  • 0

#5 Kristall89

Kristall89

    Новый участник

  • Members
  • Pip
  • 10 сообщений


Отправлено 06 февраля 2024 - 20:24

Если я вас правильно понял, можете попробовать что-то подобное

https://gist.github....f900b5c7abde853

Спасибо, любопытный вариант.


  • 0

#6 Kristall89

Kristall89

    Новый участник

  • Members
  • Pip
  • 10 сообщений


Отправлено 01 апреля 2024 - 20:13

Если я вас правильно понял, можете попробовать что-то подобное

https://gist.github....f900b5c7abde853

Напишу для истории: да, получилось разобраться и сделать через metafunc, еще раз спасибо за помощь :)


  • 0



Темы с аналогичным тегами selenium, webdriver, python, pytest, fixtures

Количество пользователей, читающих эту тему: 0

0 пользователей, 0 гостей, 0 анонимных