81
Делаем кроссбраузерные тесты поверх Webdriver Павлов Игорь 2gis.ru @rnd2gis

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

  • Upload
    sqalab

  • View
    537

  • Download
    0

Embed Size (px)

DESCRIPTION

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

Citation preview

Page 1: Делаем кроссбраузерные тесты поверх Webdriver

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

2gis.ru @rnd2gis

Page 2: Делаем кроссбраузерные тесты поверх Webdriver

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

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

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

проектов

2

Page 3: Делаем кроссбраузерные тесты поверх Webdriver

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

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

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

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

3

Page 4: Делаем кроссбраузерные тесты поверх Webdriver

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

Page 5: Делаем кроссбраузерные тесты поверх Webdriver

Webdriver

5

Page 6: Делаем кроссбраузерные тесты поверх Webdriver

Webdriver Local End

The WebDriver Wire Protocol (Json Wire Protocol)

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

6

Page 7: Делаем кроссбраузерные тесты поверх Webdriver

Webdriver Remote End

WebDriver W3C Draft

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

7

Page 8: Делаем кроссбраузерные тесты поверх Webdriver

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

Page 9: Делаем кроссбраузерные тесты поверх Webdriver

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

9

Page 10: Делаем кроссбраузерные тесты поверх Webdriver

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

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

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

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

10

Page 11: Делаем кроссбраузерные тесты поверх Webdriver

Примеры

Page 12: Делаем кроссбраузерные тесты поверх Webdriver

Click

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

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

• MAY: scrollIntoView

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

WebDriver W3C Clicking

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

12

Page 13: Делаем кроссбраузерные тесты поверх Webdriver

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

Firefox OK

Opera OK

Internet Explorer OK

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

13

Page 14: Делаем кроссбраузерные тесты поверх Webdriver

Click: а так?Chrome FAIL

Firefox OK

Opera OK

Internet Explorer NOTHING

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

14

Page 15: Делаем кроссбраузерные тесты поверх Webdriver

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

Firefox OK

Opera OK

Internet Explorer NOTHING

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

15

Page 16: Делаем кроссбраузерные тесты поверх Webdriver

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

Page 17: Делаем кроссбраузерные тесты поверх Webdriver

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

• анимации?

• ...

17

Page 18: Делаем кроссбраузерные тесты поверх Webdriver

onload

AJAX:

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

18

Page 19: Делаем кроссбраузерные тесты поверх Webdriver

resize

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

19

Page 20: Делаем кроссбраузерные тесты поверх Webdriver

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

Page 21: Делаем кроссбраузерные тесты поверх Webdriver

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

Page 22: Делаем кроссбраузерные тесты поверх Webdriver

Дождаться элемента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

Page 23: Делаем кроссбраузерные тесты поверх Webdriver

JS в помощь23

Page 24: Делаем кроссбраузерные тесты поверх Webdriver

Маркеры

24

Page 25: Делаем кроссбраузерные тесты поверх Webdriver

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

driver.execute_script(script, element)

01.

02.

25

Page 26: Делаем кроссбраузерные тесты поверх Webdriver

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

Page 27: Делаем кроссбраузерные тесты поверх Webdriver

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

Page 28: Делаем кроссбраузерные тесты поверх Webdriver

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

driver.execute_script(script, marker)

marker.click()

01.

02.

03.

28

Page 29: Делаем кроссбраузерные тесты поверх Webdriver

Итог

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

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

2. Инъекции JS

Проблема

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

29

Page 30: Делаем кроссбраузерные тесты поверх Webdriver

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

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

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

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

30

Page 31: Делаем кроссбраузерные тесты поверх Webdriver

Фреймворк

Page 32: Делаем кроссбраузерные тесты поверх Webdriver

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

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

32

Page 33: Делаем кроссбраузерные тесты поверх Webdriver

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

Page 34: Делаем кроссбраузерные тесты поверх Webdriver

Уровень Driver34

Page 35: Делаем кроссбраузерные тесты поверх Webdriver

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

Page 36: Делаем кроссбраузерные тесты поверх Webdriver

Driver inheritance36

Page 37: Делаем кроссбраузерные тесты поверх Webdriver

Driver inheritanceclass TestDriver(Remote):

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

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

self._browser = None

01.

02.

03.

04.

37

Page 38: Делаем кроссбраузерные тесты поверх Webdriver

WebElement inheritance38

Page 39: Делаем кроссбраузерные тесты поверх Webdriver

WebElement inheritanceclass TestWebElement(WebElement):

def __init__(self, driver,web_element):

self.__dict__.update(web_element.__dict__)

self.driver = driver

01.

02.

03.

04.

39

Page 40: Делаем кроссбраузерные тесты поверх Webdriver

find_element(s) override40

Page 41: Делаем кроссбраузерные тесты поверх Webdriver

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

Page 42: Делаем кроссбраузерные тесты поверх Webdriver

TextWebElement extension42

Page 43: Делаем кроссбраузерные тесты поверх Webdriver

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

Page 44: Делаем кроссбраузерные тесты поверх Webdriver

Итог

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

44

Page 45: Делаем кроссбраузерные тесты поверх Webdriver

Уровень PageObject45

Page 46: Делаем кроссбраузерные тесты поверх Webdriver

УровеньPageObject

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

Page 47: Делаем кроссбраузерные тесты поверх Webdriver

Page

47

Page 48: Делаем кроссбраузерные тесты поверх Webdriver

Map

48

Page 49: Делаем кроссбраузерные тесты поверх Webdriver

Markers

49

Page 50: Делаем кроссбраузерные тесты поверх Webdriver

Page

50

Page 51: Делаем кроссбраузерные тесты поверх Webdriver

Page

class Page(object):

def __init__(self, driver):

self.driver = driver

self._map = None

01.

02.

03.

04.

51

Page 52: Делаем кроссбраузерные тесты поверх Webdriver

Components

52

Page 53: Делаем кроссбраузерные тесты поверх Webdriver

Components

class Map(TestWebElement):

pass

class Marker(TestWebElement):

pass

01.

02.

03.

04.

05.

53

Page 54: Делаем кроссбраузерные тесты поверх Webdriver

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

Page 55: Делаем кроссбраузерные тесты поверх Webdriver

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

Page 56: Делаем кроссбраузерные тесты поверх Webdriver

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

class Map(TestWebElement):

selectors = {self': '#map'}

class Marker(TestWebElement):

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

01.

02.

03.

04.

05.

56

Page 57: Делаем кроссбраузерные тесты поверх Webdriver

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

Page 58: Делаем кроссбраузерные тесты поверх Webdriver

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

Page 59: Делаем кроссбраузерные тесты поверх Webdriver

Итог

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

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

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

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

59

Page 60: Делаем кроссбраузерные тесты поверх Webdriver

Уровень Action60

Page 61: Делаем кроссбраузерные тесты поверх Webdriver

УровеньAction

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

Page 62: Делаем кроссбраузерные тесты поверх Webdriver

Определяем клик в маркер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

Page 63: Делаем кроссбраузерные тесты поверх Webdriver

Итог

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

63

Page 64: Делаем кроссбраузерные тесты поверх Webdriver

Уровень Test64

Page 65: Делаем кроссбраузерные тесты поверх Webdriver

УровеньTest

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

Page 66: Делаем кроссбраузерные тесты поверх Webdriver

Test Case"""

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

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

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

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

"""

01.

02.

03.

04.

05.

06.

07.

66

Page 67: Делаем кроссбраузерные тесты поверх Webdriver

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

Page 68: Делаем кроссбраузерные тесты поверх Webdriver

Уровень Framework68

Page 69: Делаем кроссбраузерные тесты поверх Webdriver

УровеньFramework

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

Page 70: Делаем кроссбраузерные тесты поверх Webdriver

Framework

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

• runner

• data providers

• ...

70

Page 71: Делаем кроссбраузерные тесты поверх Webdriver
Page 72: Делаем кроссбраузерные тесты поверх Webdriver

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

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

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

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

72

Page 73: Делаем кроссбраузерные тесты поверх Webdriver

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

Page 74: Делаем кроссбраузерные тесты поверх Webdriver

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

Page 75: Делаем кроссбраузерные тесты поверх Webdriver

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

Opera 23,49 %

Firefox 14,33 %

Internet Explorer 9,99 %

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

75

Page 76: Делаем кроссбраузерные тесты поверх Webdriver

2gis.ru

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

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

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

76

Page 77: Делаем кроссбраузерные тесты поверх Webdriver

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

Page 78: Делаем кроссбраузерные тесты поверх Webdriver

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

Page 79: Делаем кроссбраузерные тесты поверх Webdriver

4. chrome -> ie -> firefox79

Page 80: Делаем кроссбраузерные тесты поверх Webdriver

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

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

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

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

80

Page 81: Делаем кроссбраузерные тесты поверх Webdriver

Вопросы?

Павлов Игорь

[email protected]

@nwlunatic

81