método indefinido 'visita' cuando se usa RSpec y Capybara en rieles

89

No puedo hacer que el capibara funcione con rspec. Me da este error:

undefined method `visit' for #<RSpec::Core::ExampleGroup::Nested_1:0x16529f8 @example=nil>

Sé que hay muchas publicaciones sobre esto, pero ninguna de las soluciones me funciona. La mayoría de ellos implican que las especificaciones no están en / spec / features, en lo que está la mía.

Primero el error:

$bundle exec rspec spec
F

Failures:

  1) security signs users in
     Failure/Error: visit "/sessions/new"
     NoMethodError:
       undefined method `visit' for #<RSpec::Core::ExampleGroup::Nested_1:0x16529f8 @example=nil>
     # ./spec/features/security_spec.rb:4:in `(root)'

 Finished in 0.006 seconds
 1 example, 1 failure

Failed examples:

rspec ./spec/features/security_spec.rb:3 # security signs users in

Creo que es importante tener en cuenta que al principio estaba usando URL Helper 'new_sessions_path' y seguía dándome un error undefined local variable or method 'new_sessions_path'. Sé que es válido porque:

$ rake routes
logout_sessions GET    /sessions/logout(.:format) sessions#logout
       sessions POST   /sessions(.:format)        sessions#create
   new_sessions GET    /sessions/new(.:format)    sessions#new
      contracts POST   /contracts(.:format)       contracts#create
  new_contracts GET    /contracts/new(.:format)   contracts#new
 edit_contracts GET    /contracts/edit(.:format)  contracts#edit
                GET    /contracts(.:format)       contracts#show
                PUT    /contracts(.:format)       contracts#update
                DELETE /contracts(.:format)       contracts#destroy
           root        /                          contracts#index

Mi Gemfile:

source 'https://rubygems.org'

gem 'rails', '3.2.11'
gem 'execjs'

group :assets do
  gem 'sass-rails',   '~> 3.2.3'
  gem 'coffee-rails', '~> 3.2.1'
  gem 'uglifier', '>= 1.0.3'
end

gem 'jquery-rails'
gem 'activerecord-oracle_enhanced-adapter', '~> 1.4.1'
gem 'jruby-openssl'
gem 'therubyrhino'
gem 'kaminari'
gem 'nokogiri'

group :development do
  gem 'warbler'
end

group :test do
  gem 'rspec-rails'
  gem 'capybara'
  gem 'activerecord-jdbcsqlite3-adapter'
end

spec_helper.rb dentro de my_app / spec:

# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'

# Capybara integration
require 'capybara/rspec'
require 'capybara/rails'

# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}

RSpec.configure do |config|
  # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
  # config.fixture_path = "#{::Rails.root}/spec/fixtures"
  config.use_transactional_fixtures = true
  config.infer_base_class_for_anonymous_controllers = false
  config.order = "random"
  # Include path helpers
  config.include Rails.application.routes.url_helpers
end

my_app / spec / features / security_spec.rb:

describe "security", :type => :feature do
  it "signs users in" do
    visit "/sessions/new"
    fill_in "username", :with => "user"
    fill_in "password", :with => "pass"
    click_button "Sign In"

    page.should have_content('Login Successful')
  end
end

Intenté definir la prueba anterior con y sin :type => :feature. No hay diferencia de ninguna manera. ¿Alguna idea de lo que debería probar a continuación?

lightswitch05
fuente
Posible duplicado de Carpincho: método indefinido 'visita'
mlt
1
@mlt en el primer párrafo dije: "Sé que hay muchas publicaciones sobre esto, pero ninguna de las soluciones funciona para mí. La mayoría de ellas implican que las especificaciones no están en / spec / features, en la que está la mía". Este párrafo hace referencia específicamente a la pregunta a la que se vincula. Esta pregunta no solo tiene más votos, sino que también viene con una solución, que es diferente a la respuesta (no la solución) más votada publicada en su pregunta vinculada.
interruptor de luz 05

Respuestas:

201

Intenta agregar:

  config.include Capybara::DSL

a su bloque de configuración.

# This file is copied to spec/ when you run 'rails generate rspec:install'
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'

# Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories.
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}

RSpec.configure do |config|
  # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
  # config.fixture_path = "#{::Rails.root}/spec/fixtures"
  config.use_transactional_fixtures = true
  config.infer_base_class_for_anonymous_controllers = false
  config.order = "random"
  # Include path helpers
  config.include Rails.application.routes.url_helpers

  config.include Capybara::DSL

end
Kocur4d
fuente
No, exactamente el mismo problema, sin cambio aparente
lightswitch05
8
Esto funcionó para mí, muchas gracias. Sin embargo, no necesitaba hacer esto en mis otros proyectos. ¿Qué circunstancias harían esto necesario en un proyecto, pero no en otro? Además, ¿qué está haciendo exactamente esto?
Peter Berg
1
Me funcionó a mi también. ¡Muchas gracias!
Marian Zagoruiko
Mi archivo ya tenía el requisito 'spec_helper' que se marcó como la respuesta a este problema, pero esto funcionó para mí. ¡Gracias!
sixty4bit
Eso no funciona para mí: recibo un mensaje de error que Capybaraes una constante indefinida. Mis pruebas de pepino están usando Capybara muy bien.
digitig el
53

Agregar require 'rails_helper'en la parte superior de mi función terminó solucionando mi problema:

require 'rails_helper'

describe "security", :type => :feature do

  it "signs users in" do
    visit new_sessions_path
    fill_in "username", :with => "user"
    fill_in "password", :with => "pass"
    click_button "Sign In"

    page.should have_content('Login Successful')
  end
end

Esto me parece extraño, ya que todos los ejemplos que he visto de rspec y carpincho no tenían ese requisito, pero bueno. Problema resuelto.

Respuesta original (versiones anteriores de rspec)

require 'spec_helper'es utilizado por versiones anteriores de RSpec. La mejor respuesta sería require 'rails_helper'.

lightswitch05
fuente
4
Debes poner la parte de actualización en la parte superior de tu publicación.
nistvan
Es realmente una mala manera aceptar la propia respuesta, aunque la respuesta de Kocur4d es más precisa (y olvidar incluir el archivo rails_helper.rb no sería el problema más común). Debe cambiar la respuesta aceptada, ya que sin el cambio de configuración realizado antes de incluirlo, aún tendría el mismo error.
randmin
35

Desde Capybara 2.0, uno tiene que usar especificaciones / características de carpeta. Los comandos de Capybara ya no funcionan en especificaciones / solicitudes de carpeta.

Thillai Narayanan
fuente
2
Como dice mi pregunta, mi prueba de capibara ya estaba ubicada debajo spec/features. Pero ese es un punto válido para otras personas que podrían estar teniendo problemas.
interruptor de luz 05 de
Encuentro útil crear el directorio mkdir spec/featuresy crear un enlace simbólico ln -s spec/features spec/requests. De esta manera, las pruebas generadas se colocarán en el directorio de características.
omarshammas
Gracias @ThillaiNarayanan, este fue mi problema siguiendo una guía de configuración anterior, pero en una versión más reciente de Capybara
VegaStudios
5

Intente realizar toda su configuración en un beforebloque:

spec / features / security_spec.rb

describe "security" do
  before do
    visit "/sessions/new"
    fill_in "username", :with => "user"
    fill_in "password", :with => "pass"
    click_button "Sign In"
  end

  it "signs users in" do
    page.should have_content('Login Successful')
  end
end
Paul Fioravanti
fuente
2
En realidad, esta es una causa común del error. La visitfunción solo está disponible dentro de un itbloque. Fuente
interruptor de luz05
4
No es cierto: el código de un beforebloque se ejecuta en el contexto de ejemplo, por visitlo que funcionará tanto allí como en un itbloque.
zetetic
2
@ user912563, en última instancia, ya que resolvió su propio problema, mi respuesta realmente se convierte en una sugerencia de estilo más que cualquier otra cosa (configurar el código en beforebloques es cómo escribo mis especificaciones, y funcionan sin errores ;-)), así que creo es justo aceptar tu propia respuesta.
Paul Fioravanti
Gracias @zetetic y @ Paul-Firavanti, no sabía que beforetodavía estaba dentro del itcontexto. Usar esto hará que mis otras pruebas que requieren inicio de sesión sean mucho más limpias
lightswitch05
Esto me ayudó porque soy un novato y no tenía la prueba envuelta "" do ... end.
Danny
3

Yo también tuve este problema,

Agregar require 'rails_helper' en la parte superior de mi función terminó solucionando mi problema:

require 'rails_helper'

RSpec.describe "Products", type: :request do
 describe "GET /products" do
 it "display tasks" do
  Product.create!(:name => "samsung")
  visit products_path
  page.should have_content("samsung")
  #expect(response).to have_http_status(200)
  end
 end
end

Y agregue el 'config.include Capybara :: DSL' en rails_helper.rb

RSpec.configure do |config|

 config.fixture_path = "#{::Rails.root}/spec/fixtures"

 config.use_transactional_fixtures = true

 config.infer_spec_type_from_file_location!

 config.include Capybara::DSL

end
Sathibabu P
fuente
Agregar esa línea de configuración funcionó para mí. Es extraño porque recibía el error en uno de mis archivos de especificaciones pero no en otro archivo de especificaciones, y ambos llamaron a los mismos métodos de captación (y ambos requerían rails_helper)
Jonathan Tuzman