#rspec #capybara
#rspec #capybara
Вопрос:
При написании тестовой среды / тестов с использованием Capybara RSpec я наткнулся на это предложение для проверки того, что элемент НЕ существует:
expect(page).to have_no_button('Save') # OK
expect(page).not_to have_button('Save') # Bad
Я был в замешательстве, почему, пока не увидел, что это указано:
Используйте should_not have_ * версии с сопоставителями RSpec, потому что should_not have_ * не ожидает тайм-аута от драйвера.
Это правда? Если нет … разве не имеет смысла с точки зрения объектной модели страницы иметь метод для проверки и возврата, если <element>
существует (я обычно использую .visible?
), таким образом, вы можете использовать сопоставитель rspec для выполнения expect(page_object).to be_method_visible
или expect(page_object).not_to be_method_visible
?
В отличие от необходимости писать 2 отдельных метода в ваших объектах страницы (если это не правда, что not_to
не будет ждать)
Для примера моих методов утверждения в моей объектной модели страницы, вот что я делаю для проверки «ссылки выхода»
def logged_in?
logout_text.visible?
end
private
def logout_text
find 'a', text: 'Log Out'
end
И тогда в спецификации я бы сказал:
expect(page_object).to be_logged_in
Поэтому я бы использовал что-то подобное для других элементов.
Ответ №1:
Я не знаю, где вы столкнулись с этим предложением (может быть, оно действительно очень старое), но для любой «последней» версии Capybara (по крайней мере, за последние 4 года) при использовании сопоставителей, предоставленных Capybara, это неверно.
Предполагая have_button
, и have_no_button
являются ли предоставленные Capybara сопоставителями (не встроенным have_xxx => has_xxx?
сопоставителем RSpecs, вызывающим has_button?
метод, который вы определили в своем объекте страницы), два примера, которые вы приводите
expect(page).to have_no_button('Save')
expect(page).not_to have_button('Save')
будут вести себя одинаково. Они будут проверять наличие кнопки и возвращаться, когда она не существует, или вызывать исключение, если прошло несколько секунд Capybara.default_max_wait_time, а кнопка все еще видна на странице.
Комментарии:
1. Эти примеры были взяты с сайта, который я видел. В принципе, я хочу проверить, что кнопка НЕ существует. Я делаю объект страницы model…so для меня имело смысл создать метод , который возвращает логическое значение, если кнопка есть
visible?
, а затем просто использовать.to be_method
или.not_to be_method
. Может быть, я неправильно использую сопоставители rspec, поскольку я используюto be
вместоto have
, но я возвращаю логическое значение из моих методов (редактирование сделано в post)2. @msmith1114 Проблема в асинхронном поведении браузера, вам нужно поведение ожидания для стабильности тестирования — если вы вызываете логические методы, это будет означать, что иногда вы ожидаете, что это будет true, иногда false — какой из них он должен ждать? С помощью утверждений / ожиданий Capybara может точно знать, чего ждать. Если вы используете логические методы, вы, вероятно, захотите отключить в них ожидание, а затем самостоятельно обрабатывать ожидание / стабильность
3. @msmith Читает ваш обновленный вопрос —
logged_in?
метод никогда не будет работать — если не существует ссылки с «Выходом из системы» (должно выполняться какfind_link('Log Out')
, а не как селектор CSS) (или если ссылка не видна), find вызовет исключение — поэтому он никогда не сможет вызватьvisible?
его4. Как мне тогда структурировать его в объекте страницы? Я пытаюсь не иметь никаких методов selenium / capybara в фактической спецификации. Я хочу иметь метод, который я могу утверждать (в самой спецификации теста, в отличие от наличия утверждения в объекте страницы)
5. @msmith1114 Именно поэтому объект страницы так основан на мнениях. Для того, что вы хотите, вы, вероятно, хотите написать свои собственные сопоставления RSpec (или, по крайней мере, иметь методы, которые возвращают экземпляры сопоставителей Capybara) и включить их в свой тестовый класс — т. Е. Вам нужно в конечном итоге использовать метод с именем
be_logged_in
available в вашем тестовом примере, который возвращаетhave_link('Log Out')
Capybaras, чтобы затем вы могливызовexpect(page).to be_logged_in
— Есть много способов, которыми вы могли бы закончить с этим, проще всего, вероятно, перезаписать стандартноеbe_xxx
поведение RSpec