How can I make tests DRY in Rails and still use Capybara and Warden? (using minitest) -


my intention create few tests same form, , in these tests need capybara fill form completely. still, wanted avoid rewriting code filling form.

i'm not using rspec! i'm using minitest.

the problem i'm facing capybara method visit , warden helper method login_as not accessible capybarahelper module.

i've seen question, created module in test/support folder, methods mentioned still not accessible. how reuse code in capybara

i've seen question, code want reuse doesn't seem fit in setup method nor in teardown method. rails: premake model instance unit tests (for dry purposes)?

i've seen posts saying module should inside test_helper.rb, add more modules file messy.

so i'm wondering i'm doing wrong. i've tried adding following lines capybarahelper didn't help. raised error nomethoderror: undefined methodsetup' capybarahelper:module`.

include devise::test::controllerhelpers include warden::test::helpers 

is right way reuse code in tests? missing should included in helper module? methods work in test controller using capybarahelper:module.

here error message:

nomethoderror: undefined method `login_as' capybarahelper:module 

and here error message test using capybarahelper:module.

nomethoderror: undefined method `visit' capybarahelper:module 

here's test:

require 'test_helper'  class travelscontrollertest < actioncontroller::testcase   include devise::test::controllerhelpers   include warden::test::helpers   warden.test_mode!    test 'should accept correct fields'     capybarahelper.login     result = capybarahelper.access_and_fill_travel_page     assert_equal "/travels/success/#{travel.last.uuid}", result[:final_path]   end  end 

and here's helper created in test/support/capybara/capybara_helper.rb avoid code duplication:

require 'test_helper' require 'capybara/rails' require 'capybara/poltergeist'  module capybarahelper   def self.access_and_fill_travel_page options = {}     options.symbolize_keys!     set_js_driver     visit(rails.application.routes.url_helpers.root_path)     initial_path = current_path     #fields     fill_in('origin', with: options[:origin] || 'guarulhos')     fill_autocomplete('origin', with: options[:origin] || 'guarulhos')     fill_in('destination', with: options[:destination] || 'seul')     fill_autocomplete('destination', with: options[:destination] || 'seul')     fill_in('date_from', with: options[:date_from] || date.today+10)     fill_in('date_to', with: options[:date_to] || date.today+26)     fill_in('adults', with: options[:adults] || 1)     fill_in('children', with: options[:children] || 0)     fill_in('babies', with: options[:babies] || 0)     find('#travel-submit').click()     final_path = current_path     return {initial_path: initial_path, final_path: final_path}   end    def self.fill_autocomplete(field, options = {})     page.execute_script %q{ el = $('input[name=#{field}]').get(0) }     page.execute_script %q{ $(el).trigger('focus') }     page.execute_script %q{ $(el).trigger('keydown') }     page.all('.ui-menu-item', minimum: 1)     page.execute_script %q{ item = $('.ui-menu-item').get(0) }     page.execute_script %q{ $(item).trigger('mouseenter').click() }   end    def self.set_js_driver     capybara.javascript_driver = :poltergeist     capybara.current_driver = capybara.javascript_driver   end    def self.login     user = factorygirl.create(:user)     login_as(user, :scope => :user)   end  end 

you should use actiondispatch::integrationtest , not actioncontroller::testcase parent class tests using capybara. actioncontroller::testcase mocks out request phase , large parts of rails. depreciated in rails 5.

instead of calling methods on test helper module should mix them test classes.

class travelsintegrationtest < actiondispatch::integrationtest   include devise::test::controllerhelpers   include warden::test::helpers   include capybarahelper    warden.test_mode!    test 'should accept correct fields'     login     # ...   end end  module capybarahelper   def login(user = factorygirl.create(:user))     login_as(user, scope: :user)   end end 

apart lacking in code organization - setup steps setting warden.test_mode! should done in test_helper.rb not repeated across tests. don't throw step definitions single file either. can place them in /test/support/ example.

module sessionhelper   def login(user = factorygirl.create(:user))     login_as(user, :scope => :user)   end end  module travelhelper   def access_and_fill_travel_page     # ...   end end 

and if want keep dry use inheritance setup test classes:

class baseintegrationtest < actiondispatch::integrationtest   include devise::test::controllerhelpers   include warden::test::helpers   include sessionhelper  end  class travelsintegrationtest < baseintegrationtest   test 'should accept correct fields'     login     # ...   end end 

Comments

Popular posts from this blog

How to put a lock and transaction on table using spring 4 or above using jdbcTemplate and annotations like @Transactional? -

c# - Update a combobox from a presenter (MVP) -

How to understand 2 main() functions after using uftrace to profile the C++ program? -