Легкое веб-тестирование с Python, Pytest и Selenium WebDriver, часть 6: как читать файлы конфигураций в тестах Python Selenium |
26.08.2020 00:00 |
Автор: Энди Найт (Andy Knight) Какой браузер?Наш тест поиска DuckDuckGo отлично работает… в Chrome. Давайте еще раз посмотрим на фикстуру браузера:
И тип драйвера, и время ожидания жестко зашиты в код. Это хорошо для подтверждения работоспособности, но готовым к проду тестам нужна возможность конфигурировать на лету. Web UI-тесты нужно мочь прогонять в любом браузере. Нужно иметь возможность менять значения таймаута по умолчанию для случаев, когда какие-либо окружения медленнее прочих. Другие закрытые данные вроде логинов и паролей тоже никогда не должны отображаться в исходном коде. Как управлять подобными тест-данными? Все эти значения – это конфигурационные данные системы тест-автоматизации. Это дискретные значения, системно влияющие на прогон автоматизации. Конфигурационные данные должны подаваться, как входные данные при любом запуске тестов. Все, относящееся к тест-конфигурации или окружению, должно управляться как данные конфигурации, чтобы код автоматизации можно было использовать повторно. Источники вводаСчитывание ввода в системы тест-автоматизации возможно несколькими способами:
К сожалению, большинство ключевых тест-фреймворков не поддерживают кастомные аргументы командной строки. Переменными окружения и системными свойствами зачастую сложно управлять, и они потенциально опасны в обращении. Службы API – отличный способ передавать ввод, Unfortunately, most core test frameworks don’t support custom command line arguments. Environmental variables and system properties can be difficult to manage and potentially dangerous to handle. Service APIs are a great way to consume inputs, especially for getting secrets (like passwords) from a key management service like AWS KMS or Azure Key Vault. However, paying for such a service may not be permissible, and writing your own may not be sensible. For lean cases, config files may be the best option. Файл конфигурации – это просто файл с конфигурационными данными. Автоматизация может читать его при запуске тестов и использовать входные данные для контроля этих тестов. К примеру, конфиг-файл может описывать тип браузера для использования фикстурой браузера в нашем учебном проекте. Хорошая практика – составлять конфиг-файл в стандартном формате вроде JSON, YAML или INI. Он должен также быть плоским для возможности диффов. Наш конфиг-файлДавайте создадим конфиг-файл для нашего учебного проекта. Мы будем использовать JSON, потому что это простой, популярный и иерархичный формат. К тому же модуль json – часть стандартной библиотеки Python, которая может легко конвертировать файлы JSON в словари. Создайте новый файл tests/config.json и добавьте в него код:
JSON использует пары ключ-значение. Как уже говорилось ранее, у нашего проекта два значения конфигурации – выбор браузера и время ожидания. Выбор браузера – строка, а время ожидания – целое число. Чтение конфиг-файлов с PytestНаилучший способ читать конфиг-файлы в pytest – это фикстуры. Они могут читать конфиги до старта тестов, а затем вставлять значения в тесты или другие фикстуры. Добавьте фикстуру в файл tests/test_web.py:
Конфигурационная фикстура читает и парсит файл tests/config.json в словарь данных, используя модуль json. Жестко закодированные пути к файлам – распространенная практика. На самом деле множество инструментов и систем автоматизации будет искать файлы в множестве локаций или по паттернам имен. Область действия фикстуры установлена как "session" – фикстура будет запускаться только один раз для каждой тест-сессии. Нет необходимости заново считывать тот же самый конфиг для каждого теста – это неэффективно. Оба значения конфигурационных данных нужны при инициализации WebDriver. Обновите браузерную фикстуру:
Теперь у браузерной фикстуры есть зависимость от фикстуры конфига. Несмотря на то, что конфиг будет запускаться только один раз за сессию, браузер будет вызываться перед каждым тестом. У браузера теперь есть цепочка if-else для определения, какой тип WebDriver использовать. Сейчас поддерживается только Chrome, но скоро мы добавим другие типы. Ошибка будет выдаваться, если выбор браузера не распознан. Неявное время ожидание теперь тоже использует значение из конфигурационных данных. Так как браузерная фикстура все еще возвращает копию WebDriver, использующие ее тесты не нуждаются в переработке! Давайте запустим тесты, чтобы убедиться, что конфиг-файл работает:
Добавление новых браузеровТеперь, когда у проекта есть конфиг-файл, его можно использовать для изменения браузера. Давайте запустим тест, используя не Google Chrome, а Mozilla Firefox. Скачайте и установите последнюю версию Firefox, а затем – последнюю версию geckodriver (драйвер для Firefox). Убедитесь, что geckodriver добавлен в системные пути. Обновите код браузерной фикстуры для поддержки Firefox:
Затем обновите конфиг-файл опцией "firefox":
Перезапустите тест. ВЫ увидите, как откроется Firefox, а не Chrome! ВалидацияКонфиг-файл нормально работает, но в логике обращения с ним есть критическая уязвимость – данные не валидируются перед прогоном тестов. Фикстура браузера выдаст ошибку, если задан выбор неподдерживаемого браузера, но это будет происходить для каждого теста. Куда эффективнее выдавать ошибку один раз за тест-сессию. Более того, автотесты упадут, если в файле отсутствует ключ браузера или времени ожидания. Давайте исправим это. Добавьте новую фикстуру для валидации выбора браузера:
Фикстура config_browser зависит от фикстуры config. Как и у config, ее область действия – сессия. Она выдаст ошибку, если в конфиг-файле нет ключа "browser", или если выбранный браузер не поддерживается. И, наконец, она возвращает выбранный браузер, и тесты и прочие фикстуры могут удобно воспользоваться этим значением. Теперь добавьте фикстуру для валидации времени ожидания:
Если в конфиг-файле указано время ожидания, фикстура config_wait_time вернет его. В прочих случаях она вернет значение по умолчанию – 10 секунд. Обновите браузерную фикстуру еще раз, чтобы использовать новые фикстуры валидации:
Создание отдельных фикстурных функций для каждого значения конфигурации делает их простыми, внятными, и сфокусированными. Они также позволяют вызывающим функциям объявлять только нужные им значения. Запустите тест, чтобы убедиться, что в ситуации "счастливого пути" все работает.
Отлично! Однако для того, чтобы действительно проверить валидацию, надо пойти окольными путями. Давайте поменяем значение "browser" в файле tests/config.json на неподдерживаемый браузер "safari". Перезапустив тест, мы должны увидеть говорящее сообщение об ошибке:
Отлично! При падении четко сообщено о проблеме. А что будет, если мы уберем браузер из конфиг-файла?
Отлично! Еще одно полезное сообщение о падении. И, наконец, для финального теста нужно добавить назад валидный выбор браузера, и удалить время ожидания:
Тест должен пройти, потому что время ожидания опционально. С нашими изменениями все в порядке! Помните, иногда нужно тестировать свои тесты. Финальный кодЕще одна пара мелочей поможет нам очистить наш тестовый код. Для начала давайте переместим наши веб-фикстуры в файл conftest.py, чтобы они могли использоваться всеми тестами, а не только тестами в tests/test_web.py. Затем сделаем некоторые литеральные значения модульными переменными. Создайте новый файл tests/conftest.py со следующим кодом:
Полное содержание tests/test_web.py должно стать проще и чище:
Теперь это в духе Python! Что дальше?Код нашего учебного проекта готов, и его можно использовать как основу для новых тестов. Полный тестовый проект размещен на GitHub. Но только потому, что мы завершили программирование, не значит, что обучение закончилось. В последнем разделе мы расскажем, как вывести вашу Web UI Python-автоматизацию на новый уровень! |