python

Selenium для Python. Глава 2. Первые Шаги

  • четверг, 19 февраля 2015 г. в 02:11:41
http://habrahabr.ru/post/250921/

Продолжение перевода неофициальной документации Selenium для Python.
Перевод сделан с разрешения автора Baiju Muthukadan.
Оригинал можно найти здесь.

Содержание:


1. Установка
2. Первые Шаги
3. Навигация
4. Поиск Элементов
5. Ожидания
6. Объекты Страницы
7. WebDriver API
8. Приложение: Часто Задаваемые Вопросы

2. Первые шаги


2.1. Простое использование


Если вы установили привязку Selenium к Python, вы можете начать использовать ее с помощью интерпретатора Python.

from selenium import webdriver
from selenium.webdriver.common.keys import Keys

driver = webdriver.Firefox()
driver.get("http://www.python.org")
assert "Python" in driver.title
elem = driver.find_element_by_name("q")
elem.send_keys("pycon")
elem.send_keys(Keys.RETURN)
assert "No results found." not in driver.page_source
driver.close()

Код выше может быть сохранен в файл (к примеру, python_org_search.py), и запущен:
python python_org_search.py
Запускаемый вами Python должен содержать установленный модуль selenium.

2.2. Пошаговый разбор примера


Модуль selenium.webdriver предоставляет весь функционал WebDriver'а. На данный момент WebDriver поддерживает реализации Firefox, Chrome, Ie и Remote. Класс Keys обеспечивает взаимодействие с командами клавиатуры, такими как RETURN, F1, ALT и т.д…

from selenium import webdriver
from selenium.webdriver.common.keys import Keys

Далее создается элемент класса Firefox WebDriver.

driver = webdriver.Firefox()

Метод driver.get перенаправляет к странице URL в параметре. WebDriver будет ждать пока страница не загрузится полностью (то есть, событие “onload” игнорируется), прежде чем передать контроль вашему тесту или скрипту. Стоит отметить, что если страница использует много AJAX-кода при загрузке, то WebDriver может не распознать, загрузилась ли она полностью:

driver.get("http://www.python.org")

Следующая строка — это утверждение (англ. assertion), что заголовок содержит слово “Python” [assert позволяет проверять предположения о значениях произвольных данных в произвольном месте программы. По своей сути assert напоминает констатацию факта, расположенную посреди кода программы. В случаях, когда произнесенное утверждение не верно, assert возбуждает исключение. Такое поведение позволяет контролировать выполнение программы в строго определенном русле. Отличие assert от условий заключается в том, что программа с assert не приемлет иного хода событий, считая дальнейшее выполнение программы или функции бессмысленным — Прим. пер.]:

assert "Python" in driver.title

WebDriver предоставляет ряд способов получения элементов с помощью методов find_element_by_*. Для примера, элемент ввода текста input может быть найден по его атрибуту name методом find_element_by_name. Подробное описание методов поиска элементов можно найти в главе Поиск Элементов:

elem = driver.find_element_by_name("q")

После этого мы посылаем нажатия клавиш (аналогично введению клавиш с клавиатуры). Специальные команды могут быть переданы с помощью класса Keys импортированного из selenium.webdriver.common.keys:

elem.send_keys("pycon")
elem.send_keys(Keys.RETURN)

После ответа страницы, вы получите результат, если таковой ожидается. Чтобы удостовериться, что мы получили какой-либо результат, добавим утверждение:

assert "No results found." not in driver.page_source

В завершение, окно браузера закрывается. Вы можете также вызывать метод quit вместо close. Метод quit закроет браузер полностью, в то время как close закроет одну вкладку. Однако, в случае, когда открыта только одна вкладка, по умолчанию большинство браузеров закрывается полностью:

driver.close()

2.3. Использование Selenium для написания тестов


Selenium чаще всего используется для написания тестовых ситуаций. Сам пакет selenium не предоставляет никаких тестовых утилит или инструментов разработки. Вы можете писать тесты с помощью модуля Python unittest. Другим вашим выбором в качестве тестовых утилит/инструментов разработки могут стать py.test и nose.
В этой главе, в качестве выбранной утилиты будет использоваться unittest. Ниже приводится видоизмененный пример с использованием этого модуля. Данный скрипт тестирует функциональность поиска на сайте python.org:

import unittest
from selenium import webdriver
from selenium.webdriver.common.keys import Keys

class PythonOrgSearch(unittest.TestCase):

    def setUp(self):
        self.driver = webdriver.Firefox()

    def test_search_in_python_org(self):
        driver = self.driver
        driver.get("http://www.python.org")
        self.assertIn("Python", driver.title)
        elem = driver.find_element_by_name("q")
        elem.send_keys("pycon")
        assert "No results found." not in driver.page_source
        elem.send_keys(Keys.RETURN)

    def tearDown(self):
        self.driver.close()

if __name__ == "__main__":
    unittest.main()

Вы можете запустить тест выше из командной строки следующей командой:
python test_python_org_search.py
.
----------------------------------------------------------------------
Ran 1 test in 15.566s

OK
Результат сверху показывает, что тест завершился успешно.

2.4. Пошаговый разбор примера


Сначала были импортированы все основные необходимые модули. Модуль unittest встроен в Python и реализован на Java’s JUnit. Этот модуль предоставляет собой утилиту для организации тестов.

Модуль selenium.webdriver предоставляет весь функционал WebDriver'а. На данный момент WebDriver поддерживает реализации Firefox, Chrome, Ie и Remote. Класс Keys обеспечивает взаимодействие с командами клавиатуры, такими как RETURN, F1, ALT и т.д…

import unittest
from selenium import webdriver
from selenium.webdriver.common.keys import Keys

Класс теста унаследован от unittest.TestCase. Наследование класса TestCase является способом сообщения модулю unittest, что это тест:

class PythonOrgSearch(unittest.TestCase):

setUp — это часть инициализации, этот метод будет вызываться перед каждым методом теста, который вы собираетесь написать внутри класса теста. Здесь мы создаем элемент класса Firefox WebDriver.

def setUp(self):
    self.driver = webdriver.Firefox()

Далее описан метод нашего теста. Метод теста всегда должен начинаться с фразы test. Первая строка метода создает локальную ссылку на объект драйвера, созданный методом setUp.

def test_search_in_python_org(self):
    driver = self.driver

Метод driver.get перенаправляет к странице URL в параметре. WebDriver будет ждать пока страница не загрузится полностью (то есть, событие “onload” игнорируется), прежде чем передать контроль вашему тесту или скрипту. Стоит отметить, что если страница использует много AJAX-кода при загрузке, то WebDriver может не распознать, загрузилась ли она полностью:

driver.get("http://www.python.org")

Следующая строка — это утверждение, что заголовок содержит слово “Python”:

self.assertIn("Python", driver.title)

WebDriver предоставляет ряд способов получения элементов с помощью методов find_element_by_*. Для примера, элемент ввода текста input может быть найден по его атрибуту name методом find_element_by_name. Подробное описание методов поиска элементов можно найти в главе Поиск Элементов:

elem = driver.find_element_by_name("q")

После этого мы посылаем нажатия клавиш (аналогично введению клавиш с клавиатуры). Специальные команды могут быть переданы с помощью класса Keys импортированного из selenium.webdriver.common.keys:

elem.send_keys("pycon")
elem.send_keys(Keys.RETURN)

После ответа страницы, вы получите результат, если таковой ожидается. Чтобы удостовериться, что мы получили какой-либо результат, добавим утверждение:

assert "No results found." not in driver.page_source

Метод tearDown будет вызван после каждого метода теста. Это метод для действий чистки. В текущем методе реализовано закрытие окна браузера. Вы можете также вызывать метод quit вместо close. Метод quit закроет браузер полностью, в то время как close закроет одну вкладку. Однако, в случае, когда открыта только одна вкладка, по умолчанию большинство браузеров закрывается полностью.:

def tearDown(self):
    self.driver.close()

Завершающий код — это стандартная вставка кода для запуска набора тестов [Сравнение __name__ с "__main__" означает, что модуль (файл программы) запущен как отдельная программа («main» (англ.) — «основная», «главная») (а не импортирован из другого модуля). Если вы импортируете модуль, атрибут модуля __name__ будет равен имени файла без каталога и расширения — Прим. пер.]:

if __name__ == "__main__":
    unittest.main()

2.5. Использование Selenium с remote WebDriver


Для использования remote WebDriver (удаленного веб-драйвера) необходимо запустить Selenium server. Для запуска сервера используйте команду:
java -jar selenium-server-standalone-2.x.x.jar
Пока Selenium server запускается, вы можете видеть сообщения вида:
15:43:07.541 INFO - RemoteWebDriver instances should connect to: http://127.0.0.1:4444/wd/hub
Строка выше сообщает о том, что вы можете использовать указанный URL для подключения remote WebDriver. Ниже приводится несколько примеров:

from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

driver = webdriver.Remote(
   command_executor='http://127.0.0.1:4444/wd/hub',
   desired_capabilities=DesiredCapabilities.CHROME)

driver = webdriver.Remote(
   command_executor='http://127.0.0.1:4444/wd/hub',
   desired_capabilities=DesiredCapabilities.OPERA)

driver = webdriver.Remote(
   command_executor='http://127.0.0.1:4444/wd/hub',
   desired_capabilities=DesiredCapabilities.HTMLUNITWITHJS)

Переменная desired_capabilities — это словарь. Вместо того, чтобы использовать словари по умолчанию, вы можете явно прописать значения:

driver = webdriver.Remote(
   command_executor='http://127.0.0.1:4444/wd/hub',
   desired_capabilities={'browserName': 'htmlunit',
                         'version': '2',
                        'javascriptEnabled': True})

Перейти к следующей главе