Введение
После сообщения @polusok ссылки на пример Page Object от “adamgoucher”, я попробовал применить этот способ у себя. В итоге моя реализация выглядит практически так же за исключением одного важного момента: подключения selenium в библиотеки page object.
Использование экземпляра библиотеки
“adamgoucher” импортирует в свою библиотеку SeleniumWrapper
from SeleniumWrapper import SeleniumWrapper as wrapper
который реализует через библиотеку selenium для python в виде синглтона
Однако, у нас уже есть превосходная библиотека Selenium2Library
и реализация её подключения через кейворд Get Library Insrance
из стандартной библиотеки BuiltIn. Данный метод возвращает текущий активный экземпляр необходимой библиотеки.
Поэтому у себя я использовал именно этот метод.
Пример
Библиотека, реализующая Page Object: GooglePageObject.py
# -*- coding: utf-8 -*-
from robot.libraries.BuiltIn import BuiltIn
locators = {"search": "css=input[id='gbqfq']"
,"search_button": "css=button[id='gbqfb']"
,"result_stats":'id=resultStats'
}
def _seleniumlib():
return BuiltIn().get_library_instance("Selenium2Library")
class GooglePageObject(object):
def search (self,text):
_seleniumlib().input_text(locators["search"], text)
self._press_search_button()
_seleniumlib().wait_until_page_contains_element(locators["result_stats"])
def _press_search_button(self):
_seleniumlib().click_element(locators["search_button"])
def get_locators(self):
return locators
-
В данной библиотеке мы подключили BuiltIn, из которой используем get_library_instance для получения экземпляра “Selenium2Library”.
В дальнейшем методы “Selenium2Library” используются через _seleniumlib() (синглтон). -
Все локаторы вынесены в словарь, а для их получения в тестах написан метод get_locators. Этот метод позволяет в тесте получить нужный локатор для дальнейшего использования, а не плодить дублирующие сущности.
Тест, использующий библиотеку GooglePageObject.py
*** Settings ***
Library Selenium2Library
Library GooglePageObject.py
Suite Setup Selenium2Library.Open Browser google.com browser=ie
Suite Teardown Selenium2Library.Close Browser
*** Test Cases ***
Search text
GooglePageObject.Search automated-testing.info
${title}= Selenium2Library.Get Title
Should contain ${title} automated-testing
- В тесте мы подключаем две библиотеки: Selenium2Library и GooglePageObject
- Всю подготовительную работу мы делаем при помощи Selenium2Library: открываем браузер, переходим на заданную страницу, при необходимости выставляем таймауты, снятие скриншотов и т.д.
- В тесте мы можем совместно использовать методы как нашей библиотеки GooglePageObject, так и Selenium2Library: поиск я делаю через первую, а title уже получаю и проверяю стандартными кейвордами.
Выводы
- Паттерн Page Object предоставляет способ разделения кода работы со страницами от самих тестов.
- Организация кода Page Object в python-библиотеках является более гибкой нежели файлы ресурсов Robot Framework.
- Использование экземпляров библиотек вместо импорта позволяет управлять их подключением и переиспользовать кейворды из тестов, что делает код прозрачнее и понятнее.
- Такой подход позволяет вынести всю подготовку в сам тест, а не в дебри библиотек. Это позволяет более гибко управлять браузером и ходом теста.
- Основная работа по автоматизации происходит в python-библиотеках, что позволяет
-
Быстрее писать, рефакторить и отлаживать код.
-
Не изменяя тесты, полностью изменить внутреннюю логику работы со страницей.