Как стать автором
Обновить

Делаем PageObject правильно. Удешевляем тестирование и снижаем порог вхождения

Уровень сложности Средний
Время на прочтение 16 мин
Количество просмотров 9K
Всего голосов 45: ↑40 и ↓5 +35
Комментарии 16

Комментарии 16

А почему на Пайтоне? На хейзенбаге показывали тесты на Go, и вами же разработанный allureGo

Есть какие-то легаси тесты и на python.

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

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

Тут уже как душе угодно, всё возможно и доступно с получившейся архитектурой.

Полезный для изучения новичками подход, однако несколько устаревший: основывать фреймворк на селениуме 3 крайне плохая идея, потому что максимальная версия питона, с которым он работает - Python 3.8, который станет депрекейтед в 2024 году. Ну и сам селениум 3 давно не обновляется.

Код из статьи прекрасно работает на python 3.11.

Ну и сам селениум 3 давно не обновляется.

И не будет обновляться, при этом 4 версия больше про работу с Selenium Server, нежели с Selenium Webdriver. Если хочется чего-то действительно обновляемого, лучше посмотреть в сторону Playwright.

Я всё таки приверженец того, чтобы на первом уровне тесты читались как можно более понятно и старались содержать Arrange-Act-Assert на видимом уровне, даже, если это противоречит принципу DRY; а также, чтобы названия методов были полностью однозначны.

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

def test_main_page():
MainPage.verify_page()

Я бы вытащил сюда явное открытие страницы и verify_page заменил бы на VerifyHeaderAndNews. А лучше бы разбил на два метода, или даже на два теста. Ибо если отвалится хэдер, но будет лента - мы об этом узнаем не сразу.


Еще, кстати, вопрос, почему внутри одного проекта выбраны различные нотации именования? для классов CamelCase, а для имен файлов и методов snake_case?

Еще, кстати, вопрос, почему внутри одного проекта выбраны различные нотации именования? для классов CamelCase, а для имен файлов и методов snake_case?

https://peps.python.org/pep-0008/#package-and-module-names
Чуть ниже про классы, методы.

Какой ужасный гайдлайн у этого вашего пайтона. Но ок, вопрос закрыт, спасибо =)

А можно подробнее зачем вам вообще Singleton ? Какую проблему вы решаете?

Убираю копипасту и лишний код. Если браузер всегда один, зачем его всегда упоминать?
Код выглядит (и что немаловажно, читается) намного лучше, если сравнить "до" и "после".

Извините, но... по мне так слишком громоздко, непонятно и не удобно :). Наверное, от того и не удобно, от того что не понятно. Уверен, что не внимательно смотрел... :

  • сделайте класс браузера, оберните его в фикстуру и укажите его один раз в начале теста... зачем там Singleton и связанные с этим ограничения (только старый Selenium) - я так и не понял;

  • поиск элемента... он что один раз ищется? Ну если Stale то ещё раз... Почему бы в эту "магию" не добавить простой поиск пока не найдется в заданный таймаут?

  • таймауты.... 5 секунд на ожидание элемента... опрометчивый хардкод, ИМНО

  • отчеты... как их читать если в тесте по 60 кликов и 20 инпутов... по уму ещё скрины надо прикрутить, но тогда это неподъемная штука получится...

Не-не, каждый пишет как ему удобно, в зависимости от поставленных задач, не в коем случае не осуждаю, просто делаю иначе.

сделайте класс браузера, оберните его в фикстуру

А потом прокидывать его в параметры везде, где есть обращение к драйверу. Параметр ради параметра.

и укажите его один раз в начале теста

Не один раз в начале теста, а один раз в начале каждого теста. Зачем?

и связанные с этим ограничения (только старый Selenium)

Selenium 4.* — это про работу с Selenium Grid, который во всём хуже, чем Selenoid

поиск элемента... он что один раз ищется?

Не понял вопроса. Все операции проводятся с webelement DOM-дерева, пока он жив в дереве, зачем его еще раз искать?

таймауты.... 5 секунд на ожидание элемента... опрометчивый хардкод, ИМНО

Сделать нормальное ожидание никто не запрещает. Здесь статья про архитектуру, не про ожидание.

отчеты... как их читать если в тесте по 60 кликов и 20 инпутов...

Рекомендую к прочтению документацию к Allure — https://allurereport.org/docs/pytest/

по уму ещё скрины надо прикрутить, но тогда это неподъемная штука получится...

Скриншоты легко прикручиваются на teardown, достаточно проверить статус теста, и в случае падения делать скриншот.

Здесь статья про архитектуру, не про ожидание.

Если говорить об архитектуре, то, думаю, важно еще подчеркнуть необходимость вытаскивания из PageObject жирной логики в классы степов или хелперов (будь они не ладны), а проверки в классы ассертов.


Т.е. ну держать элемент и атомарную обертку над этим элементом - это ок.
Но как только над элементом или группой элементов будет производиться набор действий согласно бизнес логике, такие классы начинают слишком жирно разрастаться. Оглянуться не успеешь, как у тебя уже 1000+ строк в файле.

А рефачить будет больно. Лучше сразу разделять по семантике, по началу будет казаться, что это не выгодно, но на долгой дистанции очень удобно

Для Python есть Selene - в точности то же, что Selenium на Java. Точно так же позволяет писать сразу тесты вместо того, чтобы предварять их написанием собственных велосипедов-"фреймворков". Поразительно то упорство, с которым в контексте pytest люди упорно продолжают изобретать велосипеды вместо изучения готового инструмента.

Открыл случайный тест — https://github.com/yashaka/selene/blob/master/examples/run_cross_platform/tests/acceptance_test.py

Нет, по удобству даже не близко к тому что описано в статье — с таким "фреймворком" не удастся посадить manual qa писать тесты.

Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.