Автоматизированный бот на Selenium

Selenium – один из самых популярных фреймворков автоматизации тестирования. Несмотря на то, что Selenium поддерживает шесть популярных языков программирования, его можно использовать для волшебной реализации с наименьшим количеством кода в связке с Python.

Помимо автоматизированного веб-тестирования, веб-скрейпинг с  Selenium на Python – крайне популярный вариант, который вы можете реализовать с меньшим количеством кода и ошибок на Python. Как QA-инженер, я по-прежнему использую другие языки программирования, такие как Java и JavaScript в связке с Selenium, но Python – мой основной инструмент для простых/комплексных задач веб-автоматизации.

Как я уже упоминал, Python – третий по популярности язык после HTML/CSS и JavaScript. Бот на Selenium с Python может широко использоваться для автоматизации различных сценариев и задач.

В этом руководстве я подробно расскажу, как создать автоматизированного бота на Selenium с Python. Знания окажутся для вас полезными, поскольку мы коснемся различных аспектов автоматизированного тестирования с Selenium.

Инструменты для создания бота

Одной из основных целей создания бота является использование возможностей, предлагаемых Selenium для автоматизации взаимодействия с web-элементами в DOM. Существует набор инструментов Selenium для автоматизации веб-браузеров, которые можно использовать для целого ряда задач автоматизации, такие как веб-скрейпинг, автоматизированное веб-тестирование, кросс-браузерное тестирование и т.д.

Итак, давайте посмотрим на основные инструменты, необходимые для создания бота с Selenium.

Selenium

Библиотека Python – обертка над Selenium WebDriver, обеспечивает соединение и простой API для написания функциональных тестов для автоматизации веб-задач, таких как нажатие на кнопки, навигация по страницам и заполнение форм.

Скрипт теста не взаимодействует напрямую с браузером. Selenium WebDriver — это ядро фреймворка Selenium. Как говорится в этом руководстве, Selenium WebDriver играет важную роль в соединении с браузером с помощью соответствующего драйвера браузера. Однако, вы можете еще глубже погрузиться в Selenium, если хотите узнать больше о его компонентах.

Если тесты должны выполняться в локальной Selenium Grid, на целевой машине должен быть установлен соответствующий драйвер браузера: 

Firefox

GeckoDriver for Firefox (https://github.com/mozilla/geckodriver/releases)

Chrome

ChromeDriver for Chrome (https://sites.google.com/a/chromium.org/chromedriver/downloads)

Microsoft Edge

Microsoft Edge Driver (https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/)

Safari

WebDriver for Safari (https://webkit.org/blog/6900/webdriver-support-in-safari-10/)

Загружать и устанавливать драйверы браузера необходимо только если вы хотите выполнять тесты в локальном Selenium Grid. В случае с удаленным Selenium WebDriver тесты выполняются в облачном Selenium Grid (например, LambdaTest).

Фреймворки для автоматизации на Python

Python – самый популярный выбор для автоматизированного тестирования с Selenium, ведь сам по себе язык не такой многословный, поддерживает динамическую типизацию, дает беспроблемную отчетность и многое другое. Широкий спектр фреймворков Selenium поддерживает параллельное тестирование, что ускоряет время выхода на рынок.

В этом руководстве я затронул основы Selenium Python, так позвольте мне углубиться в популярные фреймворки Selenium для автоматизации тестирования:

PyUnit (Unittest)

Unittest (или PyUnit) – это фреймворк для тестирования на Python по умолчанию, который поставляется «из коробки». Этот фреймворк вдохновлен другим популярный фреймворком JUnit.

Unittest обеспечивает простое и гибкое выполнение тест-кейсов с быстрой генерацией отчетов о тестировании. Unittest использует camelCase вместо соглашения об именовании snake_case в Python.

Руководство по Selenium PyUnit может стать хорошей отправной точкой для тех, кто хочет использовать фреймворк для автоматизированного тестирования.

PyTest

PyTest – это открытый фреймворк для тестирования, который поддерживает модульное тестирование, функциональное и тестирование API. Он доступен для Python версии 3.5 и выше. 

Объектная модель страницы (POM) в Selenium Python играет важную роль в улучшении поддержки и переиспользовании кода. Я отдаю предпочтение PyTest, а не PyUnit из-за богатого набора плагинов – настоящего блага для QA-инженеров.

Вот несколько популярных плагинов PyTest для QA-инженеров:

  • pytest-randomly

  • pytest-cov

  • pytest-django

  • pytest-bdd

Если вы хотите рассмотреть все аспекты автоматизации тестирования с Selenium и PyTest, обратитесь к этому руководству. Оно окажется полезным как новичкам, так и профессионалам, и поможет узнать, как использовать фреймворк PyTest для автоматизации.

Robot

Robot – это открытый фреймворк для автоматизации, который позволяет писать тест-кейсы на Gherkin. Лучше всего работает в методологии Behaviour Driven Development (BDD) в связке с Selenium и Gherkin. Robot также используется для приемочного TDD и автоматизации роботизированных процессов (RPA). 

Ядро Robot написано на Python, но он также может работать с Jython и IronPython. Изначально он не поддерживает параллельное тестирование, но предоставляет множество простых в использовании расширений и библиотек.

Для демонстрации реализации бота Selenium с Python я собираюсь использовать фреймворк PyTest.

Behave

Behave – фреймворк для тестирования, работающий в связке с Behavior-Driven Development (BDD). У него обширная документация и он хорошо поддерживается сообществом. Еще он обеспечивает интеграцию с Django и Flask – двумя самыми популярными веб-фреймворками на Python. 

Behave также пригодится для blackbox – тестирования. Связка BDD, Behave и Selenium имеет свой собственный набор преимуществ и недостатков, но это все еще отличный фреймворк для автоматизации тестирования на Python.

Помимо тех, что я перечислил, есть еще ряд полезных фреймворков, которые можно изучить, чтобы на полную использовать возможности Selenium и Python.

Планировщики задач для Python

Планировщики задач – это программы, которые позволяют планировать задачи и сценарии через определенные промежутки времени. С другой стороны, сценарии также можно планировать или запускать при достижении определенных условий.

Планировщик задач можно использовать для запуска пакетного файла (или .bat), который запускает соответствующий скрипт на Python. 

Вот некоторые распространенные программы, обеспечивающие планирование задач на Python:

Cron

Cron – планировщик задач, который основывается на времени в Unix-подобных операционных системах, таких как Linux и macOS. Он позволяет планировать такие задачи, как создание резервных копий, логирование и запуск скриптов.

Планировщик задач Windows

Планировщик задач – компонент ОС Windows, который позволяет автоматически создавать и запускать практически любую задачу. Обычно, система и некоторые приложения поддерживают автоматизацию и обслуживание по расписанию. Такие задачи, как дефрагментация диска, очистка диска, обновления и т.д. могут быть запланированы автоматически с помощью планировщика задач Windows.

Планировщик задач Windows работает, отслеживая время и события на компьютерах, и выполняет задачу, если выполняются необходимые условия.

Для текущей задачи я собираюсь использовать планировщик задач Windows вместе с библиотекой Win32com – тонкой оберткой на Python, которая помогает автоматизировать приложения Windows. 

Теперь, когда мы коснулись неотъемлемых аспектов создания бота на Selenium и Python, давайте испачкаем руки реализацией.

Создание бота на Selenium с Python

Выполните указанные ниже шаги, чтобы создать среду разработки для нашей реализации:

Создание виртуальной среды и установка зависимостей

Виртуальная среда (или virtualenv) — инструмент для создания изолированных сред Python. Для этой цели в Python есть модуль venv, который поддерживает создание облегченных «виртуальных сред» с изолированными каталогами.

Вы можете ознакомиться с этим руководством для быстрого погружения в автоматизированное тестирование с помощью Selenium и Python.

python3 -m venv env
  1. Выполните одну из команд ниже, чтобы активировать эту виртуальную среду.

Windows

.\env\Scripts\activate

Linux

source env/bin/activate
  1. Выполните следующую команду, чтобы установить Selenium для Python:

pip install selenium
  1. Выполните следующую команду, чтобы установить фреймворк PyTest:

pip install pytest
  1. Установите пакет pywin32 для работы с планировщиком задач Windows:

 pip install pywin32

Структура папок для тестовых скриптов

Проект состоит из двух файлов:

  • main.py – Содержит основной скрипт, который позволяет входить в платформу LambdaTest и получать подробную информацию о соответствующих тестах.

  • scheduler.py – Содержит реализацию для планирования запуска тестов.

Реализация бота

Для демонстрации создания бота Selenium с Python мы автоматизируем тестовый сценарий входа на платформу LambdaTest. Тестируемый URL-адрес — https://accounts.lambdatest.com/login

Поскольку тест демонстрируется в LambdaTest Grid, я использую удаленный WebDriver в Selenium вместо локального. Для начала мы импортируем необходимые пакеты.

from selenium import webdriver

Мы определим две переменные, в которые положим имя пользователя и ключ доступа, комбинация которых используется для доступа к облачной LambdaTest Grid. Имя пользователя и ключ доступа доступны со страницы профиля LambdaTest.

username = "<YOUR USERNAME>" access_key = "<YOUR ACCESS KEY>"

Создадим класс TestClass со следующим функционалом:

  • Setup_method – функция настройки удаленного драйвера и его свойств.

# Generate capabilities from here: https://www.lambdatest.com/capabilities-generator/ # setUp runs before each test case and def setup_method(self): desired_caps = {        "build": "your build name",        "name": "your test name",        "platform": "Windows 10",        "browserName": "Chrome",        "version": "92.0",        "selenium_version": "3.13.0",        "geoLocation": "IN",        "chrome.driver": "91.0", } """ Setup remote driver        -------        username and access_key can be found on the lambdatest platform   """ self.driver = webdriver.Remote(        command_executor="https://{}:{}@hub.lambdatest.com/wd/hub".format(        username, access_key        ),        desired_capabilities=desired_caps )
  • Teardown_method – функция для разрыва соединения после каждого тест-кейса.

def teardown_method(self):        self.driver.quit()
  • Test_login – Реализация этой функции используется для входа в дашборд LambdaTest. Здесь я использую SendKeys в Selenium для заполнения формы входа, чтобы войти на сайт LambdaTest. Вот синтаксис метода SendKeys в Selenium Python:

element.send_keys("text to enter")

Для определения местоположения соответствующих веб-элементов я использую локатор XPath в Selenium. Однако вы можете использовать другие популярные локаторы Selenium, такие как ID, Name, linktext и т.д. для определения местоположения веб-элементов.

Ниже показан синтаксис метода find_element_by_xpath() в Selenium Python. В качестве альтернативы вы также можете использовать метод driver.find_element(By.XPATH) для определения местоположения элемента с помощью локатора XPath.

element = driver.find_element_by_xpath("xpath_here")   driver.find_element(By.XPATH, "xpath")

Вот как выглядит весь метод входа в систему (test_login):

def test_login(self):        """        this function logins you in lambdatest dashboard        """        LOGIN_URL = "https://accounts.lambdatest.com/login"        DASHBOARD_URL = "https://accounts.lambdatest.com/dashboard"        self.driver.get(LOGIN_URL)        login_email = self.driver.find_element_by_xpath(            "//input[@id='email']"        )        login_password = self.driver.find_element_by_xpath(            "//input[@id='password']"        )        login_button = self.driver.find_element_by_xpath(            "//button[@id='login-button']"        )          login_email.send_keys(email)        login_password.send_keys(password)        login_button.click()          # if we are on right page        if self.driver.current_url == DASHBOARD_URL :            assert True            # time to get recent tests            self.get_recent_tests()        else:            print(" something went wrong !!")            assert False
  • Get_recent_tests – Как только я вошел в дашборд LambdaTest, извлекаю из него все последние тесты.

Как видно выше, .cut-text — общий класс для всех тегов, которые нам нужно прочитать. Далее я сделаю веб-скрейпинг для получения необходимой информации.

titles = self.driver.find_elements_by_class_name("cut-text")

Здесь я получаю текст из соответствующих тегов:

def get_recent_tests(self):        titles = self.driver.find_elements_by_class_name("cut-text")        titles_list = []        for i in titles:            titles_list.append(i.text)        message = ' '.join(titles_list[0::2])        print(message)        send_email(message)

Как видно из реализации, мы используем Selenium 3 Grid для тестирования. С выпуском стабильной версии Selenium 4 многие QA-инженеры переносят тесты в Selenium 4 Grid. Прежде чем сделать это, я рекомендую сравнить Selenium 3 и Selenium 4, чтобы можно было беспрепятственно переносить тесты.

Отправка электронных писем через Selenium для Python

В Python есть встроенная библиотека smtplib для отправки электронных писем с защищенным подключением с использованием SMTP_SSL() и .starttls(). Библиотека smtplib использует протокол RFC 821 для SMTP.

Для отправки электронного письма через smtplib я создал функцию, которая принимает сообщение в виде строки и отправляет электронное письмо.

def send_email(message):    context = ssl.create_default_context()    try:        server = smtplib.SMTP(smtp_server,port)        server.ehlo() # Can be omitted        server.starttls(context=context) # Secure the connection        server.ehlo() # Can be omitted        server.login(sender_email, sender_password)        server.sendmail(sender_email, receiver_email, message)        server.close()    except:        print(" failed to send email ")

Так выглядит итоговая реализация main.py.

from selenium import webdriver import smtplib, ssl   port = 587 smtp_server = "smtp.gmail.com" sender_password = "<YOUR_PASSWORD>" sender_email = "<YOUR_EMAIL>" receiver_email = "<EMAIL_WHERE_YOU_WANT_TO_SEND>"   def send_email(message):    context = ssl.create_default_context()    try:        server = smtplib.SMTP(smtp_server,port)        server.ehlo() # Can be omitted        server.starttls(context=context) # Secure the connection        server.ehlo() # Can be omitted        server.login(sender_email, sender_password)        server.sendmail(sender_email, receiver_email, message)        server.close()    except:        print(" failed to send email ")   username = "<YOUR_LAMBDATEST_USERNAME>" access_key = "<YOUR__LAMBDATEST_ACCESS_KEY>"   class TestClass():    def setup_method(self):        desired_caps = {            "build": "your build name",            "name": "your test name",            "platform": "Windows 10",            "browserName": "Chrome",            "version": "92.0",            "selenium_version": "3.13.0",            "geoLocation": "IN",            "chrome.driver": "91.0",        }        """        Setup remote driver                -------                username and access_key can be found on lt platform          """        self.driver = webdriver.Remote(            command_executor="https://{}:{}@hub.lambdatest.com/wd/hub".format(                username, access_key            ),            desired_capabilities=desired_caps,        )      # tearDown runs after each test case    def teardown_method(self):        self.driver.quit()      def test_login(self):        """        this function logins you in lambdatest dashboard        """        LOGIN_URL = "https://accounts.lambdatest.com/login"        DASHBOARD_URL = "https://accounts.lambdatest.com/dashboard"        self.driver.get(LOGIN_URL)        login_email = self.driver.find_element_by_xpath(            "//input[@id='email']"        )        login_password = self.driver.find_element_by_xpath(            "//input[@id='password']"        )        login_button = self.driver.find_element_by_xpath(            "//button[@id='login-button']"        )          login_email.send_keys(email)        login_password.send_keys(password)        login_button.click()          # if we are on the right page        if self.driver.current_url == DASHBOARD_URL :            assert True            # time to get recent tests            self.get_recent_tests()        else:            print("something went wrong !!")            assert False      def get_recent_tests(self):               titles = self.driver.find_elements_by_class_name("cut-text")        titles_list = []        for i in titles:            titles_list.append(i.text)        message = ' '.join(titles_list[0::2])        send_email(message)

Планирование теста Selenium на Python

Планировщик позволяет запланировать выполнение тестовых скриптов в заданный момент времени или при заданных условиях. Для этой задачи я использую планировщик задач Windows, который представляет из себя приложение с графическим интерфейсом. Я использую библиотеку Win32com для программного планирования триггеров.

Win32com — библиотека API, тонкая оболочка Python, которая позволяет автоматизировать приложения Windows, как экземпляры планировщика задач Windows.

Планировщик задач Windows использует объекты COM (Component Object Model), что позволяет управлять приложениями Windows из другой программы или скрипта. COM-объекты определяются в реестре Windows. Поскольку COM-объекты сами по себе являются «объектами», их можно использовать для тестового скрипта и с ними можно взаимодействовать программно.

Краткий код на Python для запуска тестового скрипта в планировщике задач Windows:

  • Определение клиента win32com из библиотеки pywin32:

scheduler = win32com.client.Dispatch('Schedule.Service') scheduler.Connect() root_folder = scheduler.GetFolder('\\') task_def = scheduler.NewTask(0)
  • Настройка важных аргументов

start_time: Установите время запуска скрипта.

start_time = datetime.datetime.now() + datetime.timedelta(minutes=1)

Repetition.Duration: продолжительность времени (в днях), в течение которого необходимо повторять выполнение программы. В данном случае я хочу запустить этот скрипт на 10 дней.

#Repeat for 10 days num_of_days = 10 trigger.Repetition.Duration = "P"+str(num_of_days)+"D"

Repetition.Interval: Переменная указывает, с каким интервалом должна выполняться программа. Здесь я настроил запуск скрипта через каждые 6 часов.

#For every 6 hour trigger.Repetition.Interval = "PT6H"

action.Path: Путь к интерпретатору Python или бинарному файлу pytest.

action.Path = r'C:\Users\vinayak\selenium_test\env\Scripts\pytest.exe'

action.Arguments: Путь к скрипту, который должен выполняться.

action.Arguments = r'C:\Users\vinayak\selenium_test\main.py'

Для кода планировщика давайте создадим файл scheduler.py.

import datetime import win32com.client   scheduler = win32com.client.Dispatch('Schedule.Service') scheduler.Connect() root_folder = scheduler.GetFolder('\\') task_def = scheduler.NewTask(0)   # Start time of script start_time = datetime.datetime.now() + datetime.timedelta(minutes=1)   # for running it one time TASK_TRIGGER_DAILY = 1 trigger = task_def.Triggers.Create(TASK_TRIGGER_DAILY)   #Repeat for 10 day num_of_days = 10 trigger.Repetition.Duration = "P"+str(num_of_days)+"D"   #For every 6 hour trigger.Repetition.Interval = "PT6H"  trigger.StartBoundary = start_time.isoformat()   # Create action TASK_ACTION_EXEC = 0 action = task_def.Actions.Create(TASK_ACTION_EXEC) action.ID = 'TRIGGER BATCH' action.Path = r'C:\Users\vinayak\selenium_test\env\Scripts\pytest.exe' action.Arguments = r'C:\Users\vinayak\selenium_test\main.py'   # Set parameters task_def.RegistrationInfo.Description = 'Test Task' task_def.Settings.Enabled = True task_def.Settings.StopIfGoingOnBatteries = False   # Register task # If task already running, it will be updated TASK_CREATE_OR_UPDATE = 6 TASK_LOGON_NONE = 0 root_folder.RegisterTaskDefinition(    'Test Task',  # Task name    task_def,    TASK_CREATE_OR_UPDATE,    '',  # No user    '',  # No password    TASK_LOGON_NONE

Обертка

Selenium Webdriver с Python используется для таких задач, как веб-скрейпинг или тестирование приложений. Но автоматизацию можно использовать и иначе, как мы использовали ее в нашем случае. В этом руководстве мы рассмотрели, как создать автоматизированного бота на Selenium с Python.

Аналогично планировщик задач Windows можно использовать многими способами, не только для планирования задач для приложений Windows. Также она позволяет запускать сценарии в фоновом режиме без необходимости помнить о них постоянно.


Приглашаем всех желающих на открытый урок «Написание автотестов для UI-части интернет-магазина и формирование отчётности».


ссылка на оригинал статьи https://habr.com/ru/company/otus/blog/653847/

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *