Почему я получаю сообщение об ошибке «неопределенный метод« ожидаем »» при запуске системного теста на Rails? - PullRequest
0 голосов
/ 24 апреля 2020

Когда я запускаю системный тест с использованием rails test:system, я получаю следующую ошибку:

Error:
PaymentSessionsTest#test_payment_succesful_if_valid_details_provided:
NoMethodError: undefined method `expect' for #<PaymentSessionsTest:0x00007fffd82485d0>
Did you mean?  exec
    test/system/payment_sessions_test.rb:26:in `block in <class:PaymentSessionsTest>'

Фон

Я пишу свой первый системный тест для рельсов, и у меня есть страница, на которой требуется время, чтобы загрузить. Из документации Capybara рекомендуется использовать метод expect, например. expect(page).to have_current_path(payment_success_url), который будет использовать поведение ожидания Capybara (поэтому время ожидания теста не истечет до загрузки страницы). Однако, когда я делаю это, я получаю сообщение об ошибке выше.

Я немного сбит с толку относительно того, является ли expect частью Capybara или RSpe c. Это в документации Capybara, поэтому я предполагаю, что это должно просто работать , но я в настоящее время застрял.

Соответствующий исходный код

# test\system\payment_sessions_test.rb

require "application_system_test_case"

class PaymentSessionsTest < ApplicationSystemTestCase
  setup do
    @event = events(:one)
  end

  test "payment successful if valid details provided" do
    # Enter payment details on invite page
    visit event_url(@event)
    fill_in "Your name", with: "John Doe"
    fill_in "Email", with: "test@test.com"
    fill_in "Gift amount", with: "20"
    click_on "Pay"

    # Stripe Checkout
    fill_in "cardNumber", with: "4242424242424242"
    fill_in "cardExpiry", with: "01#{Date.today.next_year.strftime("%y")}" # grab year always as next year in 2 digit format
    fill_in "cardCvc", with: "123"
    fill_in "Name on card", with: "Mr John Doe"
    fill_in "billingPostalCode", with: "N1 7GU"
    click_on "Pay"

    # Payment success page
    expect(page).to have_current_path(payment_success_url) # ensure Capybara waits for page to load after clicking Pay
    assert_selector "h1", text: "Payment successful!"
  end

end
# test\application_system_test_case.rb

require "test_helper"

class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
  driven_by :selenium, using: :chrome, screen_size: [1400, 900]
  # driven_by :selenium, using: :headless_chrome

  def setup
    # ensure url helpers use correct host and port for system tests
    Rails.application.routes.default_url_options[:host] = Capybara.current_session.server.host
    Rails.application.routes.default_url_options[:port] = Capybara.current_session.server.port
  end

end
# test\test_helper.rb

ENV['RAILS_ENV'] ||= 'test'
require_relative '../config/environment'
require 'rails/test_help'
require 'bcrypt' # required for devise (used when creating encrypted password for user fixtures)
require 'pry'

class ActiveSupport::TestCase
  include HashidsHelper

  # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
  fixtures :all

  # Add more helper methods to be used by all tests here...
  include Devise::Test::IntegrationHelpers # include devise test helpers in all tests

  setup do
    # set hashid for each event record
    # NB. can't set using fixtures as event.id is dynamic
    FixMissingHashidsService.run
  end
end
# Gemfile

group :test do
  # Adds support for Capybara system testing and selenium driver
  gem 'capybara', '>= 2.15'
  gem 'selenium-webdriver'
  # Easy installation and use of chromedriver to run system tests with Chrome
  # gem 'chromedriver-helper'
  # Using chromedriver in Windows, added to path, via WSL1
end

Используются детали и версии

  • Rails 5.2.3
  • Запуск через WSL (1) и использование бинарного драйвера Windows (Chrome открывает и запускает тесты - другие тесты не используют expect работает нормально)
  • Использование тестового шлюза Stripe Checkout в тесте (ie. На самом деле он идет к checkout.stripe.com/pay/cs_test_etc ...) как часть теста поток

Ответы [ 4 ]

1 голос
/ 24 апреля 2020

Как уже упоминалось Артуром, expect является частью RSpe c. Если вы используете minitest, вам нужно использовать минимальные утверждения, предоставленные Capybara, которые вы уже делаете с assert_selector. То, что вам не хватает, это assert_current_path - https://rubydoc.info/github/teamcapybara/capybara/Capybara/Minitest/Assertions#assert_current_path -instance_method

assert_current_path(payment_success_url)

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

  1. Глобально Capybara.default_max_wait_time = 20 в одном из ваших установочных файлов. У этого недостатка есть потенциальное увеличение времени до сбоя во всех ваших тестах

  2. Для блока действий. Это увеличивает максимальное время ожидания для всех утверждений внутри блока (индивидуальное максимальное не общее)

   Capybara.using_wait_time(20) do
     assert_current_path(payment_success_url)
     assert_selector "h1", text: "Payment successful!"
   end

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

assert_current_path(payment_success_url, wait: 20)

Примечание: вы можете захотеть чтобы использовать что-то вроде https://github.com/thoughtbot/fake_stripe вместо прямого удара в Stripe во время большинства ваших тестов по соображениям производительности

Примечание: вы всегда должны предпочитать одно из представленных утверждений Capybara над простым assert при работе с чем-либо, связанным с браузером, в ваших системных тестах.

0 голосов
/ 27 апреля 2020

Для этой проблемы определение matcher снаружи rspec должно решить проблему. Добавление следующих двух строк поверх этого файла позволит вам использовать метод expect вне контекста RSpec

require "application_system_test_case"
require "minitest/autorun"                             # new line
require "rspec/expectations/minitest_integration"      # new line
class PaymentSessionsTest < ApplicationSystemTestCase
 setup do
   @event = events(:one)
 end

 test "payment successful if valid details provided" do
   # Enter payment details on invite page
   visit event_url(@event)
   fill_in "Your name", with: "John Doe"
   fill_in "Email", with: "test@test.com"
   fill_in "Gift amount", with: "20"
   click_on "Pay"

   # Stripe Checkout
   fill_in "cardNumber", with: "4242424242424242"
   fill_in "cardExpiry", with: "01#{Date.today.next_year.strftime("%y")}" # 
   grab year always as next year in 2 digit format
   fill_in "cardCvc", with: "123"
   fill_in "Name on card", with: "Mr John Doe"
   fill_in "billingPostalCode", with: "N1 7GU"
   click_on "Pay"

   # Payment success page
   expect(page).to have_current_path(payment_success_url) # ensure Capybara 
   waits for page to load after clicking Pay
   assert_selector "h1", text: "Payment successful!"
 end

end
0 голосов
/ 24 апреля 2020

Я решил это, выполнив следующее:

  • Удалите строку expect из теста (это действительно часть RSpe c, а не Capybara - спасибо @ artur. prado )
  • Добавить Capybara.default_max_wait_time = 20 к application_system_test_case.rb (я установил 20, потому что тестовый шлюз Stripe Checkout очень медленный. Прелесть Capybara в том, что он не ждет целых 20 секунд, просто до 20 секунд - он запустится, как только сможет). Это может иметь и другие последствия, учитывая, что Capybara устанавливает значение по умолчанию в 2 секунды. Учитывая, что этот тест взаимодействует со сторонним доменом, я согласен с ним, но покупатель остерегается.
# test\application_system_test_case.rb

require "test_helper"

class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
  driven_by :selenium, using: :chrome, screen_size: [1400, 900]
  # driven_by :selenium, using: :headless_chrome

  Capybara.default_max_wait_time = 20 # Stripe Checkout test gateway is slooooow

  def setup
    # ensure url helpers use correct host and port for system tests
    Rails.application.routes.default_url_options[:host] = Capybara.current_session.server.host
    Rails.application.routes.default_url_options[:port] = Capybara.current_session.server.port
  end

end

РЕДАКТИРОВАТЬ: вместо того, чтобы устанавливать максимальное время ожидания глобально, см. Лучший вариант в Thomas's ответ .

0 голосов
/ 24 апреля 2020

expect принадлежит RSpec. Это действительно в документации по Capybara, но в разделе RSpe c, поэтому вы получаете сообщение об ошибке. Попробуйте вместо этого использовать assert.

...