Делаем кроссбраузерные тесты поверх webdriver

Post on 16-Jun-2015

537 Views

Category:

Education

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

Презентация доклада Игоря Павлова на конференции SQADays-14, Львов 8-9 ноября 2013

TRANSCRIPT

Делаем кроссбраузерные тестыповерх WebdriverПавлов Игорь

2gis.ru @rnd2gis

Обо мне• В 2ГИС 1+ год

• Команда автоматизации тестрования

• Работал над инструменами тестирования для всех внешних web-

проектов

2

О чем будет• Откуда проблемы кроссбраузерности?

• Примеры проблем кроссбраузерности

• Решение - фреймворк

• Практические рекомендации

3

Откудапроблемы?

Webdriver

5

Webdriver Local End

The WebDriver Wire Protocol (Json Wire Protocol)

https://code.google.com/p/selenium/wiki/JsonWireProtocol

6

Webdriver Remote End

WebDriver W3C Draft

http://www.w3.org/TR/webdriver

7

Интерфейс команды один8

Реализация разная

9

О чем будет• Откуда проблемы кроссбраузерности?

• Примеры проблем кроссбраузерности

• Решение - фреймворк

• Практические рекомендации

10

Примеры

Click

1. В центр элемента

2. Viewport содержит элемент

• MAY: scrollIntoView

3. Должен быть видим*

WebDriver W3C Clicking

http://www.w3.org/TR/webdriver/#clicking

12

Click: все хорошо?Chrome OK

Firefox OK

Opera OK

Internet Explorer OK

клик в желтый div

13

Click: а так?Chrome FAIL

Firefox OK

Opera OK

Internet Explorer NOTHING

клик в желтый div

14

Click: или даже так?Chrome FAIL

Firefox OK

Opera OK

Internet Explorer NOTHING

клик в желтый div

15

Click: динамический контент16

Click: другие проблемы• прозрачность (opacity)?

• анимации?

• ...

17

onload

AJAX:

• проверить отсутствие элемента

18

resize

Опера не поддерживает

19

С Оперой все грустно. Пока...20

Решенияпримеров

Дождаться элементаdriver.implicitly_wait(5)

start = time.time()

while not result and time.time() < start + timeout:

try:

result = driver.find_element_by_id("id")

except:

pass

01.

02.

03.

04.

05.

06.

22

JS в помощь23

Маркеры

24

JQuery clickscript = "arguments[0].click();"

driver.execute_script(script, element)

01.

02.

25

Поднимаем нужный маркер26

Поднимаем нужный маркер27

Поднимаем нужный маркерscript = "arguments[0].style.zIndex++;"

driver.execute_script(script, marker)

marker.click()

01.

02.

03.

28

Итог

Расширяем свои возможности засчет:

1. Продуманных обработок ошибок

2. Инъекции JS

Проблема

Как не умереть от поддержки тестов с этим всем?

29

О чем будет• Откуда проблемы кроссбраузерности?

• Примеры проблем кроссбраузерности

• Решение - фреймворк

• Практические рекомендации

30

Фреймворк

Цель фреймворка:1. сделать тесты понятными и читаемыми

2. контролировать ньюансы кроссбраузерного запуска

32

Пять уровней33

Уровень Driver34

Уровень DriverЦель: расширить возможности базового элемента

Driver inheritance36

Driver inheritanceclass TestDriver(Remote):

def __init__(self, *args, **kwargs):

super(TestDriver, self).__init__(*args, **kwargs)

self._browser = None

01.

02.

03.

04.

37

WebElement inheritance38

WebElement inheritanceclass TestWebElement(WebElement):

def __init__(self, driver,web_element):

self.__dict__.update(web_element.__dict__)

self.driver = driver

01.

02.

03.

04.

39

find_element(s) override40

find_element(s) override:with onload solutiondef find_element(self, *args, **kwargs):

try:

wait_for_element_appear(*args, **kwargs)

element = self.driver.find_element(*args, **kwargs)

except TimeoutException:

raise ElementNotFound(kwargs["value"], kwargs["by"])

return TestWebElement(self.driver, element)

01.

02.

03.

04.

05.

06.

07.08.

41

TextWebElement extension42

TextWebElement extensionclass TestWebElement(WebElement):

***

def find_element_by_sizzle(self, sizzle_selector):

pass

def javascript_click(self):

pass

01.

02.

03.

04.

05.

06.

07.

08.

43

Итог

TestWebElement — "всему голова"

44

Уровень PageObject45

УровеньPageObject

Цель: описать приложение компонентами* и связать их

Page

47

Map

48

Markers

49

Page

50

Page

class Page(object):

def __init__(self, driver):

self.driver = driver

self._map = None

01.

02.

03.

04.

51

Components

52

Components

class Map(TestWebElement):

pass

class Marker(TestWebElement):

pass

01.

02.

03.

04.

05.

53

Связь page.map: map()54

map()

@property

def map(self):

selector = Map.selectors['self']

if self._map is None:

element = self.driver. ### перенос

find_element_by_css_selector(selector)

self._map = Map(self.driver, element)

return self._map

01.

02.

03.

04.

05.

06.

07.

08.

55

Изолируем взаимодействие слокаторами

class Map(TestWebElement):

selectors = {self': '#map'}

class Marker(TestWebElement):

selectors = {'self': '.marker'}

01.

02.

03.

04.

05.

56

Связь map.markers: markers()57

markers()

class Map(TestWebElement):

...

def get_markers(self):

selector = Marker.selectors['self']

elements = self. ### перенос

find_elements_by_css_selector(selector)

return [Marker(elem) for elem in elements]

01.

02.

03.

04.

05.

06.

07.

58

Итог

Получили удобные* методы доступа к карте и маркерам

*Удобно для нас, это:

1. Работа в контексте приложения,

2. Легче контролировать изменения локаторов.

59

Уровень Action60

УровеньAction

Цель: добавить компонентам действия (из бизнес-логики)

Определяем клик в маркерclass Marker(TestWebElement):

def _original_click(self, *args, **kwargs):

super(Marker, self).click(*args, **kwargs)

def click(self):

self.bring_to_front()

self._original_click()

01.

02.

03.

04.

05.

06.

07.

62

Итог

Описали какими функциональными действия обладают компоненты

63

Уровень Test64

УровеньTest

Цель: реализовывать тест кейсы понятно

Test Case"""

- Делаем поиск

- На карте кликаем в маркер

- Название фирмы в коллауте ищем в результатах поиска

ОР: Название фирмы в коллуте есть в результатах поиска

"""

01.

02.

03.

04.

05.

06.

07.

66

Test

def test_firmcallout_title_in_firmcards_titles(self):

self.page.searchBar.catalogTab.search('пиво')

self.page.map.markers[0].click()

title = self.page.map.firmCallout.title

self.assertTrue(title in self.page.searchResults)

01.

02.

03.

04.

05.

67

Уровень Framework68

УровеньFramework

Цель: предоставить все необходимое для организации и запуска тестов

Framework

Фреймворк для юнит-тестов:

• runner

• data providers

• ...

70

О чем будет• Откуда проблемы кроссбраузерности?

• Примеры проблем кроссбраузерности

• Решение - фреймворк

• Практические рекомендации

72

Рекомендации

1. А нужно ли оно вам?74

Статистика пользователей 2gis.ruChrome 37,58 %

Opera 23,49 %

Firefox 14,33 %

Internet Explorer 9,99 %

за период с 14 сентября по 14 октября 2013г

75

2gis.ru

• Одностраничное приложение

• И это очень много JS

• А JS в разных браузерах...нужно тестировать

76

2. Проверенные методы selenium77

3. Проблемный* браузер - вперед78

4. chrome -> ie -> firefox79

О чем будет• Откуда проблемы кроссбраузерности?

• Примеры проблем кроссбраузерности

• Решение - фреймворк

• Практические рекомендации

80

Вопросы?

Павлов Игорь

i.pavlov@2gis.ru

@nwlunatic

81

top related