[Заметка] Использование Page Object в Robot Framework

Введение

После сообщения @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
  1. В данной библиотеке мы подключили BuiltIn, из которой используем get_library_instance для получения экземпляра “Selenium2Library”.
    В дальнейшем методы “Selenium2Library” используются через _seleniumlib() (синглтон).

  2. Все локаторы вынесены в словарь, а для их получения в тестах написан метод 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
  1. В тесте мы подключаем две библиотеки: Selenium2Library и GooglePageObject
  2. Всю подготовительную работу мы делаем при помощи Selenium2Library: открываем браузер, переходим на заданную страницу, при необходимости выставляем таймауты, снятие скриншотов и т.д.
  3. В тесте мы можем совместно использовать методы как нашей библиотеки GooglePageObject, так и Selenium2Library: поиск я делаю через первую, а title уже получаю и проверяю стандартными кейвордами.

Выводы

  1. Паттерн Page Object предоставляет способ разделения кода работы со страницами от самих тестов.
  2. Организация кода Page Object в python-библиотеках является более гибкой нежели файлы ресурсов Robot Framework.
  3. Использование экземпляров библиотек вместо импорта позволяет управлять их подключением и переиспользовать кейворды из тестов, что делает код прозрачнее и понятнее.
  4. Такой подход позволяет вынести всю подготовку в сам тест, а не в дебри библиотек. Это позволяет более гибко управлять браузером и ходом теста.
  5. Основная работа по автоматизации происходит в python-библиотеках, что позволяет
  • Быстрее писать, рефакторить и отлаживать код.

  • Не изменяя тесты, полностью изменить внутреннюю логику работы со страницей.

3 лайка

Кстати, по поводу связки robot framework + page object - есть интересная библиотечка: ссылка на либу

Мы с ней немного игрались. Она сыровата, но в принципе можно взять за основу и довести до ума. А так - в принципе интересный подход.