Behave+Selenium Webdriver
Для тестирования Web-проектов
Гребенщиков Иван
БАРС Груп
iv.grebenschikov@gmail.com
2
Основные части

Selenium Webdriver

Behave

Их интеграция

Возможные
проблемы и пути их
решения
3
BDD или TDD?
4
Selenium RC
5
Selenium Webdriver
6
Behave

BDD фреймворк для тестирования на python.

Поддержка большого числа языков для
описания feature-файлов.

Возможно добавить пред- и пост-действия,
выполняемые относительно шага, сценария,
функциональности или всего запуска.

Возможно отмечать отдельные
функциональности и сценарии тэгами.
7
Структура файлов
features_selenium/
├── 0.positions_and_rights.feature
├── 1.institutions_and_preiods.feature
├── environment.py
├── __init__.py
├── steps
│ ├── constants.py
│ ├── edo.py
│ ├── __init__.py
│ ├── settings.py
│ └── webservice.py
├── z.webservice.feature
8
environment.py

before_step, after_step

before_scenario, after_scenario

before_feature, after_feature

before_tag, after_tag

before_all, after_all
9
Пример
def before_all(context):
context.personal_area_interface =
False
context.firefox_binary =
FirefoxBinary(firefox_path=settings.FIRE
FOX_BIN)
context.settings = settings
10
Состав feature-файла

Описание тестируемого функционала.

Описание предусловий, если есть.

Описание сценария.

Описание шагов.
11
Пример
Функционал: Авторизация
Предыстория:
Дано страница приветствия
Сценарий: авторизация супер-администратора
Если Ввести в поле login_login значение admin
И Ввести в поле login_password значение admin
И Авторизоваться в системе, нажав кнопку Войти
на странице приветствия
То откроется страница рабочего стола
12
Обработка шагов
Сценарий: Список классов
Если нажать на кнопку выбора в поле "Предмет / Группа (Класс)"
То откроется окно "Выбор группы учеников"
_____________________________________________
@when(u'нажать на кнопку выбора в поле "Предмет /
Группа (Класс)"')
def step(context):
url = get_action_url('select_window_action')
resp = get_response_with_status_200(context, url)
title = "title:'Выбор группы учеников"
window_title =
resp.content[resp.content.find(title):resp.content.find(
title)+len(title)]
context.acd['window_title'] = window_title
@then(u'откроется окно "Выбор группы учеников"')
def step(context):
assert 'Выбор группы учеников' in
context.acd['window_title']
13
Сценарий: Авторизация
Когда я ввожу логин "admin" и пароль "admin"
И нажимаю кнопку "Войти"
То мне открывается страница личного кабинета
_______________________________________
@when(u'я ввожу логин "{login}" и
пароль "{password}"')
def step(context, login, password):
context.login = login
context.password = password
14
Пример интерфейса
15
Типичный шаг
Если в поле Дата с окна Классный журнал установить
значение 16.03.2015
_______________________________________________________
@step(u'в поле {field_label} окна {win_name}
установить значение {value}')
def step_find_and_fill_field(context,
field_label, win_name, value):
win = get_win_object(context, win_name)
field = win.get_field_by_name(field_label)
field.set_value(value)
16
Получаем
окно
Получаем
элемент
окна
Производим
действие
Проверяем
результат
17
Page Elements

Объект окна

Объект текстового поля

Объект поля ввода даты

Объект кнопки

Объект грида
18
Window
class Window(object):
def __init__(self, win_id, title, driver):
self.win_id = win_id
self.title = title
self.driver = driver
# Словарь вида {field_label: field_id}
self.fields_init_data = {}
# Словарь вида {field_label: FieldObj}
self.init_fields = {}
self.__init_win_fields()
...
19
Window
def close(self):
self.driver.execute_script(u"""
Ext.getCmp('{0}').close()
""".format(self.win_id))
20
Window
def get_field_by_name(self, field_label):
if field_label in self.init_fields:
return self.init_fields[field_label]
else:
self.__init_field(field_label)
return self.init_fields[field_label]
21
Field
class Field(object):
def __init__(self, field_id, driver,
field_label=None):
self.field_id = field_id
self.label = field_label
self.driver = driver
...
22
Field
def set_value(self, value):
self.field_object.click()
self.field_object.clear()
self.field_object.send_keys(value)
self.field_object.send_keys(Keys.ENTER)
23
Возможные проблемы

Время прохождения тестов

Зависимость тестов
24
Зависимость тестов

Dump БД

Fixtures

FactoryBoy
25
Зависимость тестов
class UserFact(factory.django.DjangoModelFactory):
class Meta:
model = 'myapp.User'
django_get_or_create = ('username',)
username = 'john'
26
Параллельный запуск тестов
Число потоков
Определяем feature-файлы
для каждого потока
Запускаем
behave
27
Что получилось

С помощью FactoryBoy создали начальные
данные, что позволило делать
независимыми тесты отдельной
функциональности.

Параллельный запуск позволил снизить
время прохождения тестов.
28
Полезные ссылки

http://pythonhosted.org/behave/ - behave
документация

http://selenium-python.readthedocs.io/ - python
+ selenium webdriver

https://factoryboy.readthedocs.io - FactoryBoy
документация
29
Спасибо за внимание!

Применение behave+webdriver для тестирования Web-проектов