Статьи

Основы капибары и улучшение ваших тестов

Влюбленная капибара

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

Основной характеристикой, к которой стремятся разработчики, является возможность иметь модульные тесты, которые легко писать и которые легко поддерживать. Это особенно верно в средах Agile / TDD, где написание тестов является второй натурой. Ожидается, что эти тесты дадут хорошие и быстрые отзывы о качестве кода. Со временем число тестов растет, и поддерживать тесты может быть настоящим кошмаром, особенно когда тесты не модульные и не достаточно простые.

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

Анатомия капибары

Как и Watir, Capybara — это библиотека / гем, созданная для использования поверх базового веб-драйвера. Он предлагает удобный DSL (домен-специфический язык), который используется для описания действий, выполняемых базовым веб-драйвером.

Когда страница загружается с использованием DSL (и соответствующего веб-драйвера), Capybara попытается найти соответствующий элемент в DOM (объектная модель документа) и выполнить действие, такое как кнопка щелчка, ссылка и т. Д.

Вот некоторые из веб-драйверов, поддерживаемых Capybara:

  • стойка :: тест :
    По умолчанию это работает с rack :: test driver. Этот драйвер значительно быстрее других драйверов, но в нем отсутствует поддержка JavaScript, и он не может получить доступ к ресурсам HTTP вне приложения, для которого создаются тесты (приложение Rails, приложение Sinatra).

  • селен-вебдрайвер :
    Capybara поддерживает селен-webdriver, который в основном используется в веб-платформах автоматизации. Он поддерживает JavaScript, может получать доступ к ресурсам HTTP за пределами приложения, а также может быть настроен для тестирования в автономном режиме, что особенно полезно для сценариев CI. Для настройки использования этого драйвера вам необходимо добавить:
    Capybara.default_driver = :selenium

  • капибара-вебкит :
    Для истинного безголового тестирования с поддержкой JavaScript мы можем использовать драйвер capybara-webkit (gem). Он использует QtWebKit и работает значительно быстрее, чем селен, поскольку не загружает весь браузер. Чтобы настроить использование этого драйвера, вам необходимо добавить:
    Capybara.default_driver = :webkit

Установка

Capybara поддерживает версии Ruby> = 1.9 и может использоваться в двух режимах: пользовательском интерфейсе и в автономном режиме.

В режиме пользовательского интерфейса добавьте следующее в Gemfile :

 gem install capybara
gem install #{web_driver_on_which_capybara_runs}

Для безголового режима:

 gem install capybara
gem install #{web_driver_on_which_capybara_runs}
apt-get install firefox
apt-get install xvfb
gem install selenium-webdriver # if using selenium-webdriver
gem install capybara-webkit # if using capybara-webkit
apt-get install libqtwebkit-dev # if using capybara-webkit

Базовый DSL

Capybara поставляется с очень интуитивно понятным DSL, который используется для выражения действий, которые будут выполнены. Это список основных команд, которые используются:

 visit('page_url') # navigate to page
click_link('id_of_link') # click link by id
click_link('link_text') # click link by link text
click_button('button_name') # fill text field
fill_in('First Name', :with => 'John') # choose radio button
choose('radio_button') # choose radio button
check('checkbox') # check in checkbox
uncheck('checkbox') # uncheck in checkbox
select('option', :from=>'select_box') # select from dropdown
attach_file('image', 'path_to_image') # upload file

Используя DSL, Capybara будет искать следующие атрибуты в DOM при попытке найти элемент:

  • Текстовое поле ( fill_in
  • Нажмите ссылку / кнопку ( click_linkclick_button
  • Флажок / переключатель / раскрывающийся список ( checkuncheckchooseselect
  • Загрузить файл ( attach_file

Продвинутый DSL

Для сценариев, в которых базовый DSL не может помочь, мы используем селекторы xpath и CSS (по умолчанию будут использоваться селекторы CSS). Это очень распространено, поскольку современные веб-приложения обычно содержат много кода JavaScript, который генерирует элементы HTML с атрибутами, которые генерируют значения (например, случайные идентификаторы и т. Д.)

Чтобы найти конкретный элемент и нажать на него, мы можем использовать:

 find('xpath/css').click

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

 find('xpath/css').text

Чтобы использовать селекторы xpath, просто измените следующее значение конфигурации:

 Capybara.default_selector = :xpath

Тип селектора может быть указан при необходимости:

 find(:xpath, 'actual_xpath')

Matchers

При попытке найти элемент, используя селекторы DSL или xpath / CSS, обычно бывает два или более совпадений, что приведет к сбою Capybara с ошибкой неоднозначного соответствия . Кроме того, Капибара может выполнять частичные совпадения, что приводит к неожиданным результатам. В связи с этим важно знать о стратегиях сопоставления, поддерживаемых Capybara:

  • : one — выдает ошибку, когда найдено более одного совпадения
  • : first — просто выбирает первый матч — не используйте это!
  • : Предпочитать — находит все совпадающие элементы, но вернет только точное совпадение, отбрасывая другие совпадения
  • : smart — зависит от значения Capybara.exact . Если установлено значение true , оно будет вести себя как : один . В противном случае он сначала будет искать точные совпадения. Если найдено несколько совпадений, возникает неоднозначное исключение. Если ничего не найдено, он будет искать неточные совпадения и снова выдает неоднозначное исключение, когда найдены несколько неточных совпадений.

Обзорный

Чтобы избежать непредвиденного поведения (например, неоднозначных совпадений), хорошей практикой является использование части DOM, в которой будет выполнено некоторое действие:

 within(:xpath, 'actual_xpath') do
  fill_in 'Name', :with => 'John'
end

Сначала Капибара будет искать в DOM с помощью селектора xpath. Затем внутри этой части DOM будет выполнен дополнительный поиск текстового поля.

Пользовательские селекторы

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

 Capybara.add_selector(:my_selector) do
  xpath { "actual_xpath" }
end
find(:my_selector)

Мы даже можем передавать аргументы селекторам (так же, как они являются методами):

 Capybara.add_selector(:my_selector) do
  xpath { |arg| "//xpath/#{arg}" }
end
find(:my_selector, arg)

или объединить пользовательские селекторы с областью видимости:

 Capybara.add_selector(:my_selector_area) do
  xpath { "actual_xpath" }
end

within(:my_selector_area) do
  fill_in 'Name', :with => 'John'
  fill_in 'Email', :with => '[email protected]'
end

Вот несколько рекомендаций по использованию Capybara DSL, пользовательских селекторов, а также области видимости и соответствия:

  • Область действия DOM, на которой выполняется действие.
  • Внутри этой области предпочтите Capybara DSL, когда это возможно.
  • Если это невозможно, используйте относительные селекторы xpath / CSS в области видимости.
  • Селекторы xpath / CSS должны быть как можно более мелкими внутри области видимости.

JavaScript и обработка асинхронных вызовов

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

 click_link('foo')
click_link('bar')

Здесь, скажем, нажатие на ссылку «foo» запускает асинхронный процесс, такой как Ajax-запрос, который добавляет ссылку «bar». Вероятно, второе утверждение не будет выполнено, поскольку ссылка еще не существует.

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

 Capybara.default_wait_time

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

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

Capybara также поддерживает выполнение JavaScript через:

 page.execute_script()

где код JavaScript можно передать так:

 page.execute_script("$('#area button.primary').click()")

Использование капибары с RSpec

Капибара, естественно, подходит для RSpec и никакой специальной интеграции не требуется.

 describe "Create place scenario" do
  context "Go to home page" do
    it "opens homepage" do
      visit(get_homepage)
    end
  end
  context "Click on create object link" do
    it "opens create new object form" do
      find(:homepage_navigation_create_object).click
    end
  end
end

До сих пор мы видели, как мы можем использовать DSL для взаимодействия с элементами страницы, но есть одно предостережение: с каждым новым контекстом будет создаваться новый сеанс Capybara, что, вероятно, не то, что мы хотим.
Capybara :: Session.new: драйвер помогает решить эту проблему. Например:

 session = Capybara::Session.new :selenium # instantiate new session object
session.visit() # use it to call DSL methods

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

Хорошая практика: определите метод в spec_helper.rb, который будет возвращать объект сеанса и использовать этот объект сеанса при вызове всех методов Capybara в контексте RSpec ( session.visitsession.find

Отладка

Есть несколько методов отладки Capybara, таких как:

 save_and_open_page # saves current snapshot of page
print page.html # retrieve current state of DOM
save_sceenshot('screenshot.png') # save screenshot

Есть еще один метод, который я считаю более полезным для отладки: гемы pry и pry-debugger .

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

  • gem install pry-debugger
  • require 'pry'
  • добавьте binding.pry Выполнение будет приостановлено на точке останова. На этом этапе используйте nextstepcontinue

Для получения дополнительной информации об этих драгоценных камнях проверьте:
* Прай
* Прай-отладчик

Завершение

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