Привет. Вопрос скорее по питону, чем по собственно тестированию, но возник в процессе написания автотестов.
Есть проект с несколькими типами аккаунтов (пользователь и разные виды магазинов). Для тестирования страниц профиля, онлайн-заказа и тд работаю над фикстурой, которая в начале теста выполняет авторизацию, а в конце разлогинивается.
Файл с логинами-паролями выглядит как на скрине (сложный словарь):
Сразу уточняю: я в курсе, что это не безопасно, но аккаунты типовые без каких-либо данных и дополнительных прав. Если кто-то получит к ним доступ, то узнает не больше, чем если зарегистрируется сам))))
В текущем варианте есть две одинаковых фикстуры, отдельно для юзеров (которых потом будет несколько) и для продавцов. В каждую фикстуру в виде параметра передается соответствующая часть словаря. И есть два очень похожих набора тестов, часть из которых отличаются только названиями и тем, какая фикстура в них передается.
Мне такое решение не нравится количеством кода и сложностью поддержки как минимум, ну и просто криво.
Такой код в старом варианте:
@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). Гугл говорит, что чтобы сделать параметр необязательным, нужно задать ему значение по умолчанию, но я не понимаю, какое в этой ситуации можно указать значение (или что передать в вызов в качестве параметра).
Как такое решается? В будущем фикстура будет дорабатываться - получать метку конкретного теста и выбирать из списка аккаунтов один-два нужных, например, но сейчас затык именно в технической стороне. Нагуглить пока не получилось, видимо, запрос формулирую как-то неправильно.
(Вариант "это говнокод, все надо делать совсем иначе" принимается при наличии объяснений, как именно иначе и почему так лучше)