Тестирование пользовательских сценариев с помощью Ferrum
Привет, дорогие хабражители!
Меня зовут Вадим, я представляю команду внедрения проектов группы компаний Bimeister.
В этой статье я поделюсь нашим опытом разработки автотестов для тестирования пользовательских сценариев работы с нашей платформой c помощью ruby gem — Ferrum.
Конечно, в нашей компании уже есть большая и дружная команда тестирования в группе разработки, которые покрывают тестами каждый релиз, с разной степенью автоматизации в рамках своих потребностей и KPI.
Мы же, как последняя миля перед заказчиком, поставили себе целью создать автотесты, которые:
- Покроют ключевую бизнес-функциональность наших заказчиков
- Позволят за минимальное время дать заключение о допуске релиза к установке в контур заказчика
- Создать понятный отчет для всех сторон с заключением об успешности/ошибках при тестировании релиза.
Проверка гипотезы
Для проработки гипотезы мы набросали простой тест-план для нашей задачи
Данный пример, лишь самая малая часть функциональности нашей платформы.
Для пробы пера взяли следующий стек:
- ruby 3.2.2 (rbenv)
- VM на RedOS Муром
- Gemfile:
- ferrum
- dotenv
- faker
А также logger, стандартный класс ruby, для логирования действий приложения
От приложения на рельсах на данном этапе отказались, но его создание есть в ближайших планах
Почему Ferrum
При выборе инструмента мы исходили из простоты работы с браузером, отсутствия дополнительных компонентов (web-driver) и скорости работы. Поэтому отпали Selenium и Playwright
Ferrum работает напрямую с CDP (Chrome DevTools Protocol), что освобождает от установки драйверов и позволяет контроллировать браузеры на основе Chromium напрямую. На хабре уже был обзор Ferrum
Отметим что Ferrum работает в 5–10 раз быстрее чем другие фреймворки.
Остальные браузеры (Firefox, Safari) мы не брали в расчет — у текущих заказчиков используются только Chromium подобные браузеры. Остальные браузеры тестируют коллеги из команды разработки.
Реализация
Поскольку для первого прогона у нас чистый ruby делаем:
bundle init
bundle add ferrum faker dotenv
Структура приложения будет выглядеть так:
- корень приложения
- main.rb —
Основной файл приложения
- lib
- input_data.rb —
Генерация данных для ввода в систему
- method_utils.rb —
Класс MethodUtils c перечнем методов для взаимодействия с интерфейсом системы
- modules
- management.rb —
Модуль ManagementMethods с набором методов для взаимодействия с модулем администрирования системы
- object_model.rb —
Модуль ObjectModelMethods с набором методов для управления объектной моделью системы
- process.rb —
Модуль ProcessMethods c набором методов для управления бизнес-процессами системы
- project.rb —
Модуль ProjectMethods с набором методов для управления проектами в системе
- main.rb —
- .env —
Файл с переменными окружения для хранения адреса целевого стенда, логина, пароля и других настроек приложения
- Gemfile
- Gemfile.lock
При первом подходе для ожидания загрузки всех ресурсов страницы пользовались методом sleep
, однако он не безопасный, поскольку если ожидание закончится, а ресурсы не загружены — приложение завершится с ошибкой. Из ситуации вышли написав небольшой метод для проверки завершения загрузки страницы:
def wait_for_selector(selector, timeout = 10)
start_time = Time.now
element = @browser.at_xpath(selector)
until element || Time.now - start_time > timeout
sleep 0.1
element = @browser.at_xpath(selector)
end
unless element
@logger.error("Элемент #{selector} не загружен в течении #{timeout} секунд(ы)")
abort("Ресурсы страницы не загружены в течении #{timeout} секунд(ы)")
end
end
Пример файла main.rb
require 'ferrum'
require 'faker'
require 'dotenv/load'
require_relative 'lib/input_date'
require_relative 'lib/method_utils.rb'
logger = Logger.new('logs/developer.log')
browser = Ferrum::Browser.new(headless: true, window_size: [1450, 850])
test = MethodUtils.new(browser, logger)
begin
property_params = PARAMS_PROPERTY_CREATE
property_params_update = PARAMS_PROPERTY_UPDATE
test.authorization
test.open_administrations_menu("Объектная модель")
test.open_secondary_menu("Свойства")
test.create(property_params)
test.update(property_params, property_params_update)
test.delete(property_params_update)
end
Здесь мы инициализируем экземпляр logger
, ferrum
и Модуль MethodUtils
. Далее вызываем MethodUtils
переменной test
и поскольку модуль связан с остальными модулями через require_relative
— обращаемся к методам модулей из папки Modules и идем по написанному сценарию тестирования.
Пример работы приложения
Процесс на схеме показывает работу приложения:
- Инициализируем в main.rb экземпляр
Ferrum::Browser.new
иLogger.new
- Передаем инициализированные экземпляры логгера и ferrum в модуль
MethodUtils
- В свою очередь
MethodUtils
передает дальше экземпляры в другие модули приложения - Экземпляр
Ferrum::Browser.new
вызывает через WebSocket инициализацию нового окна Сhrome через CDP - В приложении идет выполнение логики работы с браузером
- После выполнения приложения Ferrum дает сигнал на завершение работы окна браузера
Пример Лога успешного выполнения тестов
I, [2023-07-17T16:54:47.112595 #17795] INFO -- : Выбран верный провайдер (Локальный)
I, [2023-07-17T16:54:47.128303 #17795] INFO -- : В поле 'Логин' введен логин
I, [2023-07-17T16:54:47.150329 #17795] INFO -- : В поле 'Пароль' введен пароль
I, [2023-07-17T16:54:47.426656 #17795] INFO -- : Кнопка 'Войти' нажата
I, [2023-07-17T16:54:50.373433 #17795] INFO -- : Кнопка 'Администрирование' НАЖАТА
I, [2023-07-17T16:54:50.750440 #17795] INFO -- : Кнопка администрирования 'Объектная модель' НАЖАТА
I, [2023-07-17T16:54:50.802920 #17795] INFO -- : Кнопка меню (Связи) нажата
I, [2023-07-17T16:54:50.943513 #17795] INFO -- : Нажата кнопка создания 'Связи'
Что дальше
В следующих статьях мы продолжим разработку приложения для тестирования пользовательских сценариев:
- Перейдем на Ruby on Rails,
- Добавим в Faker методы генерации для наших нужд,
- Релизуем пользовательский интерфейс,
- В интерфейсе реализуем:
- Выбор стенда для тестирования, и тестов для объектной модели заказчика
- Выбор количества экземляров тестов (параллельное выполнение, нагрузочное тестирование)
- Выбор количество пользователей, проектов, процессов, объектов
- Добавим генерацию отчета по результатам тестирования,
- Поставим приложение на мониторинг,
- Добавим авторизацию и ролевую модель,
- Передадим команде аналитиков приложение автотестов под согласованные тест-планы наших заказчиков,
- Проработаем возможность проводить ПСИ (приемо-сдаточные испытания) с использованием Capybara+Cuprite+Ferrum.
На связи была команда Bimeister, не переключайтесь!