Статьи

Испытайте зараженный селеном

Тестированием часто пренебрегают в программировании, и веб-разработка ничем не отличается. Многие разработчики еще не осознали, что автоматизированные тесты могут сделать вас более продуктивными, менее напряженными и более уверенными в кодировании следующей функции. В этой статье мы сосредоточимся на использовании Selenium для автоматизации тестирования браузера.

Как веб-разработчикам, нам нужны какие-то тесты, потому что мы, конечно же, не хотим, чтобы сообщения об ошибках от пользователей наших приложений были нашими средствами тестирования. Мы хотим, чтобы тесты были автоматизированы, потому что ручное тестирование, хотя иногда и является необходимым злом, является медленным, подверженным ошибкам и скучным. Повторное ручное тестирование веб-приложения в нескольких браузерах может, прямо скажем, разрушить душу! Такой инструмент, как Selenium, поможет вам привыкнуть к автоматическому тестированию.


Возможно, вы можете относиться к этому опыту: вы открываете свой проект с целью кодирования новой функции или исправления ошибки, и вы задаетесь вопросом: «Могут ли изменения, которые я собираюсь внести, иметь непреднамеренные побочные эффекты? ?»

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

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

Это легче понять, когда вы прошли через боль программирования без хороших тестов. Соблазнительно подумать: «Я просто хочу продолжить кодирование следующей части моего приложения». Это чаще всего бывает, когда вы работаете над чем-то относительно простым. Но, как скажет любой разработчик, все может быстро усложниться. Внезапно становится страшно модифицировать код, и тогда вы действительно оцените комплексный набор тестов, чтобы поддержать вас.

Но снижение страха — это только одно преимущество. Хорошо написанные тесты служат для документирования разрабатываемой системы, и это способствует лучшему пониманию среди разработчиков и заказчиков. Посмотрев на тест, вы сможете точно сказать, как должен вести себя конкретный аспект системы. Эта концепция подчеркивается поведенческим развитием (обсуждается позже).

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

Это серьезный сдвиг в мышлении, но как только вы почувствуете, что автоматические тесты являются фундаментальной частью программирования и пожинаете плоды, вы никогда не будете оглядываться назад. Я познакомился с тестированием, когда познакомился с TDD , но, на мой взгляд, заражение тестами не обязательно должно проходить через TDD или модульное тестирование. Вам просто нужно испытать огромную ценность автоматизированных тестов и почувствовать странность в программировании, если не в рутине их написания.

Когда вы настроитесь и пожинаете плоды, вы никогда не будете оглядываться назад.

Ответом на эти аргументы может быть: «Все это звучит как то, что отнимает много времени; время, которое могло бы кодировать следующую функцию». В конце концов, у нас обычно есть ограниченное время, чтобы тратить на проект. И это правда, настройка и составление автоматических тестов требует времени и усилий. Но количество времени, которое он экономит в долгосрочной перспективе, и улучшенное качество, которое он стремится привнести в код, делают строгую рутину автоматизированного тестирования вполне оправдывающей инвестиции.

Мы будем использовать бесплатный инструмент под названием Selenium . Selenium автоматизирует браузеры; он имитирует взаимодействие пользователя с вашим веб-приложением, выполнение щелчков мышью, ввод текста и даже перетаскивание (среди прочего). Его также можно использовать для проверки того, что отображается на экране.

Умение писать хорошие тесты — это навык, который вы приобретаете с течением времени, но в этом руководстве мы обсудим, как начать тестирование браузера с использованием Selenium.


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

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

Модульные тесты не должны касаться проверки правильности совместной работы отдельных компонентов системы; вот где вступают интеграционные тесты.

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

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

Пример кода, представленный ниже, выполняет этот вид тестирования. Эти тесты говорят нам, ведет ли наше приложение то, что нам нужно, с точки зрения пользователя. Мы можем использовать Selenium для автоматизации такого рода тестов, поскольку он может имитировать взаимодействие пользователя с системой (и это можно делать с помощью реальных веб-браузеров, а также безголовых систем, таких как HtmlUnit ).

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


Какие виды тестов вы должны использовать?

Мы можем использовать Selenium для автоматизации тестов, потому что он может симулировать взаимодействие пользователя с системой.

Торт — это своего рода еда, но большинство людей (не я) советуют не есть его исключительно; это дополняет, а не заменяет другую еду. Важно отметить, что различные виды тестирования дополняют друг друга, а не участвуют в соревнованиях. Как уже упоминалось выше, они служат различным целям. Каждый из них имеет свои преимущества и недостатки, и они, безусловно, не являются взаимоисключающими.

Тесты на уровне системы, управляемые графическим интерфейсом, такие как приведенные ниже примеры, как правило, выполняются относительно медленно и поэтому не обеспечивают быстрой обратной связи. Подобные тесты также имеют тенденцию быть хрупкими, и поскольку они затрагивают большую часть кода приложения, отследить источник сбоя может быть сложно без сопровождающего полного набора модульных и интеграционных тестов. На самом деле, было бы неплохо иметь гораздо больше тестов на уровне модулей, чем тесты на системном уровне с графическим интерфейсом, для которых используется Selenium. Это не значит, что тесты Selenium бесполезны! Дело в том, что ни одного типа тестирования недостаточно.


Мы будем использовать Selenium 2. Более конкретно, мы будем использовать WebDriver, компонент Selenium 2. WebDriver заменяет API-интерфейс удаленного управления (RC) в Selenium 1 и предлагает ряд преимуществ по сравнению с RC. Например, он лучше подходит для тестирования AJAX и имеет более чистый, более объектно-ориентированный API. Он также работает совершенно иначе, чем RC. Вместо использования JavaScript для взаимодействия со страницей, WebDriver использует интерфейс автоматизации браузера, свойственный каждому браузеру. В результате он лучше имитирует реального пользователя, взаимодействующего с тестируемым веб-сайтом.

Другим компонентом Selenium является IDE, инструмент для записи и воспроизведения и плагин Firefox. Он не требует знаний программирования и полезен для пробного тестирования.

Его тесты, как правило, более хрупкие, чем сценарии RC и WebDriver, и очевидным большим недостатком является то, что он может использоваться только в Firefox. IDE предназначен для создания прототипов и не рекомендуется для серьезных испытаний .

WebDriver поддерживает широкий спектр браузеров, включая Chrome, IE, iOS и Android. Позже мы рассмотрим использование сервисов облачного тестирования, чтобы тесты могли выполняться на комбинациях браузера и операционной системы, к которым у вас иначе не было бы доступа.

Здесь WebDriver будет использоваться с Python, но доступно несколько языковых привязок, в том числе для Java, C # и PHP. Если вы не знакомы с Python, не бойтесь, вы все равно сможете следовать примерам, так как он читается как псевдокод.

Python … читается как псевдокод

Доступен ряд других интерфейсов, но нам нужны две ключевые части API WebDriver : WebDriver и WebElement . Каждый приведенный ниже пример будет работать с объектом WebDriver , который соответствует браузеру, и одним или несколькими объектами типа WebElement , которые представляют элементы на странице.

Методы для нахождения элементов на странице (обсуждаются позже) являются общими для этих двух интерфейсов. С другой стороны, такие методы, как tag_name , доступны только в WebElement . Точно так же имеет смысл, чтобы такие методы, как get_cookies и refresh были доступны в WebDriver но не в WebElement , и это действительно так.

Интересно отметить, что делается попытка сделать WebDriver стандартом W3C .


В настоящее время Selenium 2 поддерживает Python 2.6 и Python 2.7, поэтому при необходимости установите один из них. Чтобы узнать, какая у вас версия, введите в командной строке python -V . Пользователи Linux и Mac обычно уже имеют Python, но должны соблюдать осторожность при обновлении своей версии Python, поскольку операционная система может зависеть от версии, с которой поставляется ОС.

Если у вас есть Python 2.6 или 2.7, лучший способ установить пакеты для него — это pip . Если у вас есть pip, для установки Selenium 2 введите: pip install -U selenium . ( -U обновит любую вашу предыдущую версию. Пользователям Linux и Mac может понадобиться sudo ).

Чтобы получить pip в Windows, посмотрите этот вопрос переполнения стека .

Мы также будем использовать Firefox, так как это браузер, который работает с WebDriver из коробки.


Нам нужно веб-приложение для тестирования, и мы будем использовать простую игру с угадыванием чисел. Это заведомо простая программа. Веб-приложение часто тестируется на компьютере разработчика с использованием локального веб-сервера разработки, поскольку это удобно для тестирования перед развертыванием. Однако в этом случае мы будем запускать тесты для развернутого веб-приложения: http://whats-my-number.appspot.com. Это будет тестируемое приложение (AUT). (В случае, если этот сайт не работает, попробуйте http://whats-my-number-backup.appspot.com/).

Ответ (извините, что испортил веселье) — 42 .

Независимо от ввода пользователя, подсказка должна отображаться. Программа ожидает целые числа от 0 до 100 (включительно), и если пользователь вводит значение, которое не соответствует этому правилу, подсказка должна указывать на это требование. Когда пользователь пытается угадать целое число от 0 до 100, что неверно, показанная подсказка должна быть либо «слишком низкой», либо «слишком высокой». Когда вводится 42, должна отображаться подсказка «Поздравления».

Ранее мы затронули идею о том, что отличный способ четко указать, как должна вести себя система, — это написать тесты, а более поздние примеры будут включать в себя довольно полный набор тестов, которые будут отражать предполагаемое поведение системы. У нас будет форма исполняемой документации.

У нас будет форма исполняемой документации

Одна из замечательных особенностей языка, такого как Python, заключается в том, что вы можете использовать интерактивный переводчик. Для запуска интерактивного интерпретатора Python просто введите python в командной строке, и вы должны увидеть его приглашение ( >>> ). В качестве альтернативы, чтобы запустить файл сценария, используйте python script_name.py

Конечно, тестовый код обычно не запускается, но когда вы только начинаете работать с автоматизацией браузера, может быть полезно использовать интерактивный интерпретатор и вводить строку Python одновременно. Таким образом, легче понять, как WebDriver управляет браузером и имитирует реального пользователя. Хотя вместо этого вы можете запустить файл сценария и бездельничать и наблюдать, как Selenium делает свое дело, все работает гораздо быстрее, чем с обычным пользователем, поэтому выполнение команд по одной строке за раз позволяет легче понять, что команды, которые вы вводите, фактически выполняются. Это отличный способ учиться и экспериментировать.


Введите следующие строки кода в командной строке переводчика, нажимая Enter после каждого. Первый шаг — выполнить импорт:

1
from selenium import webdriver

Далее мы открываем окно браузера и заходим в AUT:

1
2
browser = webdriver.Firefox()
browser.get(‘http://whats-my-number.appspot.com/’)

Теперь мы сделаем то, что делает это тестом. Встроенный в Python оператор assert можно использовать для проверки того, что что-то истинно, и в этом случае мы используем его для проверки того, что заголовок страницы — «Какой у меня номер». Это может называться контент-тестом :

1
assert ‘What\’s My Number?’

Так как заголовок страницы правильный, Python просто дает нам еще один запрос. Неверный заголовок означал бы, что assert выдает AssertionError . AssertionError при запуске файла сценария приводит к сбою программы (что полезно).

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

Для этого мы должны заполнить форму. Если вы посмотрите HTML-код страницы игры в угадайку, то увидите, что поле ввода текста имеет атрибут name со значением «угадать». Это можно использовать для получения объекта WebElement для представления поля ввода:

1
guess_field = browser.find_element_by_name(‘guess’)

Теперь мы можем ввести предположение. WebElement есть метод send_keys :

1
guess_field.send_keys(‘1’)

Мы могли бы найти кнопку отправки и щелкнуть ее или использовать предоставленный метод submit , но вместо этого нажмите клавишу Return:

1
2
from selenium.webdriver.common.keys import Keys
guess_field.send_keys(Keys.RETURN)

Форма отправляется и страница перезагружается (AJAX не используется), и поскольку предположение слишком низкое, где-то в теле документа должно отображаться «Ваше предположение слишком низкое». Для проверки сначала нам нужен объект WebElement который представляет body HTML:

1
body = browser.find_element_by_tag_name(‘body’)

В этом случае свойство text WebElement будет отображать текст страницы. Давайте использовать это в assert :

1
assert ‘Your guess is too low’ in body.text

Опять же, успех, поэтому Python просто дает нам еще один запрос. Поскольку это неправильное предположение, «Поздравления» нигде не видно:

1
assert ‘Congratulations’ not in body.text

Наконец, мы закрываем экземпляр Firefox, который мы использовали:

1
browser.quit()

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

Выше мы использовали find_element_by_name , который полезен для элементов формы, а также find_element_by_tag_name . Другие методы локатора включают find_element_by_id и find_element_by_css_selector . Смотрите документацию Selenium для полного списка .

С точки зрения производительности, наилучшим способом выбора элемента является использование идентификатора элемента или локатора имени (как мы это делали выше). Конечно, когда у нас есть объект WebElement который соответствует желаемому элементу DOM, обычно хочется каким-то образом взаимодействовать с ним, и здесь полезны такие методы, как send_keys и click .


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

В загружаемом zip-файле, сопровождающем это руководство, ftests1.py перечисляет приведенный выше пример тестового кода в форме файла сценария. Однако есть и упущение: вы можете заметить, что вызов implicitly_wait , включенный в ftests1.py , не был указан или обсужден.

Если вы запускаете тест против системы десять раз, он должен давать одинаковый результат каждый из этих десяти раз. Тем не менее, хрупкие и ненадежные тесты, которые мы проводим, довольно распространены, и вы вполне можете столкнуться с этой проблемой, экспериментируя с тестами Selenium. Хрупкие тесты опасны, потому что, если тесты иногда терпят неудачу, когда они действительно должны пройти, вы начинаете игнорировать результаты тестов, и весь процесс тестирования обесценивается. implicitly_wait — очень полезный инструмент в борьбе с хрупкими тестами, и с этого момента вызов implicitly_wait будет использоваться во всем примере кода.


Будучи разработчиком, зараженным тестами, вы захотите узнать об инструментах xUnit . Они доступны для многих языков программирования . unittest — это инструмент xUnit, который входит в стандартную комплектацию Python. Это может показаться странным, но, хотя мы не пишем модульные тесты, unittest полезен. Например, unittest помогает структурировать и запускать тесты, а ошибки тестов приводят к появлению более полезных сообщений.

Версия unittest в Python 2.7 имеет дополнительные функции по сравнению со старыми версиями (некоторые из которых мы будем использовать), поэтому, если вы используете Python 2.6, вам необходимо установить backport : pip install unittest2

Код ниже является тестовой версией тестового кода, представленного ранее.

Как и раньше, проверяется заголовок окна браузера, 1 проверяется как предположение, и проверяется ответ программы:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
try:
  import unittest2 as unittest #for Python 2.6
except ImportError:
  import unittest
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
 
class GuessTest(unittest.TestCase):
 
  def setUp(self):
    self.browser = webdriver.Firefox()
    self.browser.implicitly_wait(3)
 
  def tearDown(self):
    self.browser.quit()
 
  def test_should_see_page_title(self):
    # Brian visits the guessing game website
    self.browser.get(‘http://whats-my-number.appspot.com/’)
 
    # He sees that «What’s My Number?»
    self.assertEqual(‘What\’s My Number?’, self.browser.title)
    
  def test_should_get_correct_hint_from_guess_too_low(self):
    # Brian visits the guessing game website
    self.browser.get(‘http://whats-my-number.appspot.com/’)
 
    # He types his guess into the form field and hits the return key
    guess_field = self.browser.find_element_by_name(‘guess’)
    guess_field.send_keys(‘1’)
    guess_field.send_keys(Keys.RETURN)
 
    # The page is reloaded and since the guess is too low,
    # ‘Your guess is too low’ is displayed
    body = self.browser.find_element_by_tag_name(‘body’)
    self.assertIn(‘Your guess is too low’, body.text)
 
    # Since this is an incorrect guess, ‘Congratulations’ is nowhere to be seen
    self.assertNotIn(‘Congratulations’, body.text)
 
 
if __name__ == ‘__main__’:
    unittest.main()

Мозг — это имя нашего «пользователя робота». Смотрите также ftests2.py в zip-файле, сопровождающем это руководство.

Отдельные тесты — это методы класса GuessTest , который наследуется от unittest.TestCase . Для получения дополнительной информации о ключевом слове self и других объектно-ориентированных аспектах Python см. Сеанс Nettuts на Python . Имена методов тестирования должны начинаться с буквенного test . Важно сделать имена методов описательными.

Конечно, assert является обязательным для любого теста, но на самом деле вместо использования оператора assert как прежде, у нас есть доступ к методам утверждения unittest. В этом случае используются assertEqual , assertIn и assertNotIn .

setUp и tearDown выполняются до и после каждого из тестовых методов, и здесь мы используем их для запуска и завершения работы экземпляра браузера WebDriver.

Последний блок, if __name__ == '__main__': unittest.main() , позволяет запускать этот скрипт unittest из командной строки. Для запуска скрипта перейдите в каталог, содержащий ftests2.py и введите: python ftests2.py . Выполнение должно привести к выводу, как это:

В идеале тесты должны проваливаться «шумно», но проходить «тихо», и, как вы можете видеть, именно это и делает unittest: для каждого метода прохождения теста печатается только период. Наконец, мы видим приветствие «ОК» (не должно быть «Хорошо сделано»?).

Как видите, принцип «Не повторяйся» нарушается, поскольку URL-адрес AUT указан в коде дважды. Тщательное тестирование позволяет проводить рефакторинг кода приложения, но не забывайте также проводить рефакторинг тестового кода.


До сих пор в наших тестах использовалось только одно предположение: 1, и, очевидно, это не очень полно. Следующий сценарий с этим ftests3.py , смотрите ftests3.py в zip-файле.

Операторы import , объявление класса, setUp и setUp и tearDown if __name__ == '__main__': все точно такие же, как в предыдущем примере. Итак, давайте сосредоточимся на вещах, которые отличаются.

Поскольку это то, что мы будем делать неоднократно, заполнение формы было помещено в собственный вспомогательный метод с именем _enter_guess_hit_return :

1
2
3
4
def _enter_guess_hit_return(self, guess):
 guess_field = self.browser.find_element_by_name(‘guess’)
 guess_field.send_keys(guess)
 guess_field.send_keys(Keys.RETURN)

Другой вспомогательный метод, _unsuccessful_guess , занимается посещением AUT, вызовом _enter_guess_hit_return и вызовом методов assert. Опять же, наш робот-пользователь может делать с именем, на этот раз давайте назовем его Берти.

01
02
03
04
05
06
07
08
09
10
def _unsuccessful_guess(self, berties_guesses, expected_msg):
 self.browser.get(‘http://whats-my-number.appspot.com/’)
 
 for berties_guess in berties_guesses:
   self._enter_guess_hit_return(berties_guess)
 
   body = self.browser.find_element_by_tag_name(‘body’)
   self.assertIn(expected_msg, body.text)
 
   self.assertNotIn(‘Congratulations’, body.text)

Вы можете заметить, что вызов _enter_guess_hit_return и выполнение утверждений происходит в цикле. Это потому, что мы зацикливаемся на berties_guesses , который является списком . berties_guesses будут переданы этому методу вызывающими тестовыми методами, которые также передадут ожидаемое сообщение expected_msg .

Теперь, чтобы использовать наших помощников в тестовых методах:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
def test_should_get_correct_hint_from_guess_too_low(self):
  berties_guesses = [‘0′, ’01’, ’17’, ’23’, ‘041’]
  expected_msg = ‘Your guess is too low’
  self._unsuccessful_guess(berties_guesses, expected_msg)
 
def test_should_get_correct_hint_from_guess_too_high(self):
  berties_guesses = [’43’, ’80’, ‘100’]
  expected_msg = ‘Your guess is too high’
  self._unsuccessful_guess(berties_guesses, expected_msg)
 
def test_should_get_correct_hint_from_invalid_input(self):
  berties_guesses = [‘a’, ‘5a’, ‘c7’, ‘1.2’, ‘9.9778’, ‘-1’, ‘-10’, ‘101’, ‘hkfjdhkacoe’]
  expected_msg = ‘Please provide a whole number from 0 to 100’
  self._unsuccessful_guess(berties_guesses, expected_msg)

Для краткости, проверка заголовка страницы была обойдена. Конечно, должен быть метод для проверки того, что когда предоставляется правильное предположение, действительно отображается «Поздравления», и вам предлагается написать этот метод (обещаю, это будет весело!).


Последний пример сценария дает нам достаточную уверенность в том, что AUT работает должным образом. Но предположим, что код приложения теперь должен измениться. Например, клиент хочет новую функцию, или мы хотим провести рефакторинг, или, возможно, модульные или интеграционные тесты обнаружили ошибку, которую тесты системного уровня не выявили (и теперь мы хотим исправить эту ошибку). В процессе изменения кода существующие тесты следует часто запускать, чтобы проблемы появлялись раньше, а не позже.

Давайте смоделируем изменение в коде приложения. Модифицированная версия игры находится по адресу http://whats-my-number-broken.appspot.com, и если вы запустите ftests3.py этой версии, вы увидите тестовый сбой:

test_should_get_correct_hint_from_guess_too_high . Тест показывает, что при изменении кода приложения была введена регрессия . Мы регулярно проводим тесты, и нам нужно учитывать только те изменения, которые были сделаны с момента последнего прохождения тестов, чтобы сузить проблему. Таким образом, написание тестов вознаградило нас чувством уверенности, а не чувством страха.


Как правило, ожидается, что веб-приложения будут функционировать должным образом в самых разных браузерах, поэтому обычно лучше тестировать с таким количеством браузеров на любом количестве платформ, на которое вы можете попасть. Когда обнаруживается проблема с системой, нередко можно услышать, как разработчик говорит: «Ну, это работает на моей машине». Это часто означает: «Мы не проверили это должным образом». В случае игры с угадыванием чисел вы можете задаться вопросом, требуется ли кросс-браузерное тестирование, но, конечно, это преднамеренно простая система.

Могут помочь облачные сервисы, такие как Sauce Labs. Sauce Labs предлагает различные комбинации браузеров и ОС . Еще один сервис — Testingbot, который предлагает тестирование на мобильных платформах .

Как вы уже видели, мы проводим тесты на общедоступных сайтах, но для сайтов, которые все еще находятся в разработке и интранет-сайтах, Sauce Labs предлагает Sauce Connect, а Testingbot предлагает Tunnel .

До сих пор примеры кода были жестко запрограммированы для использования Firefox. ftests3_remote.py , доступный в zip-файле, представляет собой расширенную версию ftests3.py которую можно легко настроить для работы с использованием определенной комбинации браузера и ОС (в пределах возможностей, предлагаемых любой службой облачного тестирования, которую мы используем). Платформа, браузер и версия браузера указываются в командной строке при запуске скрипта.

Примеры кода до сих пор были жестко запрограммированы для использования Firefox

Чтобы получить ключ API, вам нужно зарегистрироваться в таком сервисе, как Sauce Labs или TestingBot, и отредактировать метод setUp (как показано в файле), чтобы включить этот ключ. Обе услуги можно попробовать бесплатно.

ftests3_remote.py ожидает платформу в качестве первого аргумента командной строки, имя необходимого браузера в качестве второго и версию браузера, которая ожидается последней. Со ссылкой на доступные комбинации браузера и ОС Sauce Lab мы могли бы, например, запустить скрипт следующим образом: