Rspec Helper Method Not Accessible to Features - testing

I'm learning TDD and running some Feature tests and am having issues with a helper method.
I've pulled out the following method from the feature test:
todo_helper.rb
module Features
def create_todo(todo_title)
click_on "Add a new todo"
fill_in "Title", with: todo_title
click_on "Submit"
end
end
However, I'm getting the following error when I run the Feature Test.
Failures:
1) User creates todo successfully
Failure/Error: create_todo 'Buy Milk'
NoMethodError:
undefined method `create_todo' for # <RSpec::ExampleGroups::UserCreatesTodo:0x007fb1f351b150>
# ./spec/features/user_creates_todo_spec.rb:8:in `block (2 levels) in <top (required)>'
Finished in 0.34992 seconds (files took 2.01 seconds to load)
1 example, 1 failure
Failed examples:
rspec ./spec/features/user_creates_todo_spec.rb:5 # User creates todo successfully
I have two tests that are pulling this method and they are both failing. Here is the one above:
user_creates_todo_spec.rb
require "rails_helper"
feature "User creates todo" do
scenario "successfully" do
sign_in
create_todo 'Buy Milk'
expect(page).to have_css '.todos li', text: 'Buy Milk'
end
end
This is strange because I created another helper that I'm using for the sign_in method above and that is working fine, but can't figure out why the second one is not working. I isolated the create_todo method within the original feature and it passes within each Feature but not as a helper. Any help is appreciated.

Make sure you require and include the module containing your helper method in the RSpec config (spec_helper.rb or rails_helper.rb):
require "todo_helper"
Within RSpec.configure:
config.include Features

Related

Rails testing button functionality with capybara.

I have this code, I am trying to click on the button to test its functionality using guard and capybara. I get an undefined method error on guard when I have it written like this. It comes back with no errors if I comment out the click_button line. It should render a response that the import was successful as well which is being displayed by an index page.
require 'rails_helper'
require 'spec_helper'
RSpec.describe "Imports", type: :request do
it "checks the import page." do
get '/imports'
click_button "submit"
end
end
how long does the it take to load the element? if > 2 seconds (capybara default wait time is 2s) then it's most likely you will get the undefined method error...
Try increasing capybara's timeout or do it for that element only:
click_button "submit", wait: 10
If that doesn't solve your issue then assure "submit" is the correct path to your element...
By default Capybara::DSL is only included in tests of type :feature, are you also including it in type :request?

How to use #valid_attributes in a before block in rails 3 and rspec?

I'm trying different blogs with examples of Rails 3 and RSpec. Yes it's on Windows, so the answer isn't not using Windows. No choice in that. Moving on...
I am able to run the spec either with rspec spec or rake spec:models so that seems fine. However if I try to use a before block with attributes it fails on creating a Person class with those attributes. The other tests are just there to show spec can run.
Made a Person model then updated the spec
\myapp\spec\models\person_spec.rb
require 'spec_helper'
describe Person do
before(:each) do
#valid_attributes = {
:first_name => "Foo",
:last_name => "Bar"
}
end
it "should create a new instance given valid attributes" do
Person.create!(#valid_attributes)
end
it "can be instantiated" do
Person.new.should be_an_instance_of(Person)
end
it "can be saved successfully" do
Person.create.should be_persisted
end
#pending "add some examples to (or delete) #{__FILE__}"
end
Here's the output of rake spec:models command
C:\Users\laptop\Documents\Sites\myapp>rake spec:models
C:/Ruby193/bin/ruby.exe -S rspec ./spec/models/person_spec.rb
Person
←[31m should create a new instance given valid attributes (FAILED - 1)←[0m
←[32m can be instantiated←[0m
←[32m can be saved successfully←[0m
Failures:
1) Person should create a new instance given valid attributes
←[31mFailure/Error:←[0m ←[31mPerson.create!(#valid_attributes)←[0m
←[31mActiveRecord::UnknownAttributeError:←[0m
←[31munknown attribute: first_name←[0m
←[36m # ./spec/models/person_spec.rb:13:in `block (2 levels) in <top (required)>'←[0m
Finished in 0.074 seconds
←[31m3 examples, 1 failure←[0m
Failed examples:
←[31mrspec ./spec/models/person_spec.rb:12←[0m ←[36m# Person should create a new instance given valid attributes←[0m
rake aborted!
C:/Ruby193/bin/ruby.exe -S rspec ./spec/models/person_spec.rb failed
So two out of three passed just not the one with attributes.
Anything in particular that would need to be setup for a before block to run or how are attributes passed in a test with Rails 3?
Also is there a way to get rid of those ]31m and such printouts for each spec line?
Thanks
It would appear from the error that ActiveRecord can't find the attribute :first_name that you are passing as part of #valid_attributes. That is, the problem isn't with how you are using RSpec, but with the attributes you are expecting a valid model to contain.
Check that you have a :first_name field or attribute on the Person model - and verify the exact spelling (:first_name vs :firstname or some other variation)
I should update this with the answer.
The Person model did in fact contain first_name and last_name but as noted by two people above the error I was receiving pointed to ActiveRecord not finding it.
In Windows, running rake db:migrate two or three times eventually fixed it even though it wasn't missing in the model.
If you're stuck on Windows dev, this may be a good thing to know!
I finally was able to put Lubuntu on a VirtualBox on Windows 7 and it ran fine and since then I have proceeded with other examples from there.
Cheers

Why isn't my tests working for this form?

In Firefox, if I try to submit a post without a title, I get: 1 error prohibited this post from being saved.
But when I run my test. It's a different story.
My Post model has validates_presence_of :title. My test looks like:
require 'spec_helper'
describe 'Users' do
it 'registered users should not be able to post without a title', :js => true do
user = Factory(:user)
visit new_post_path
current_path.should eq(new_post_path)
fill_in 'post[markdown_description]', :with => 'Bar'
click_on 'Submit your post'
page.should have_content('error')
end
end
By the way, I am using Selenium (:js => true), because my submit button is actually an anchor link with some JS. Basically, when the link is clicked, JS triggers the form to be submitted.
Rspec returns:
Running: spec/requests/users_spec.rb
F
Failures:
1) Users registered users should be able to post
Failure/Error: page.should have_content('error')
expected there to be content "error" in ""
# ./spec/requests/users_spec.rb:13:in `block (2 levels) in <top (required)>'
Finished in 7.9 seconds
1 example, 1 failure
Failed examples:
rspec ./spec/requests/users_spec.rb:4 # Users registered users should be able to post
The request may not make it to the controller action if you have before_filters. Check the log to make sure that the correct parameters are posting and that the action is not redirecting.
Another option is to include this in your spec:
click_on 'Submit your post'
save_and_open_page
which opens the current page in the browser so you can see what is actually being rendered.

RoutingError with RSpec Controller test on Scoped Route

So I have a route that looks like this:
scope "4" do
scope "public" do
scope ":apikey" do
resources :shops
end
end
end
And a bunch of controller specs, an example of which looks like this:
describe ShopsController do
describe "when responding to a GET" do
context "#new" do
it "should create a new instance of the shop class" do
get :new
#shop.should_not_be_nil
end
end
end
end
In rake routes, as well as via a web browser, this controller/action works fine. However, RSpec throws:
1) ShopsController when responding to a GET#new should create a new instance of the shop class
Failure/Error: get :new
ActionController::RoutingError:
No route matches {:controller=>"shops", :action=>"new"}
# ./spec/controllers/shops_controller_spec.rb:9:in `block (4 levels) in <top (required)>'
When I remove the scope statements from the route, the tests work fine. Is there a way to "inform" RSpec of the route scopes?
Thanks in advance!
According to your routes, :apikey is a required parameter, so you need to add it to your get:
get :new, :apikey => "something"
Also you should change the expectation in your next line to this:
assigns[:shop].should_not be_nil
Use assigns to check the controller's instance variables, and separate should_not from the matcher with a space, not an underscore. That last bit takes some getting used to.

Failing to test Devise with Capybara

I'm building a Rails 3 app using Devise, with Capybara for UI testing. The following test is failing:
class AuthenticationTest < ActionController::IntegrationTest
def setup
#user = User.create!(:email => 'test#example.com',
:password => 'testtest',
:password_confirmation => 'testtest')
#user.save!
Capybara.reset_sessions!
end
test "sign_in" do
# this proves the user exists in the database ...
assert_equal 1, User.count
assert_equal 'test#example.com', User.first.email
# ... but we still can't log in ...
visit '/users/sign_in'
assert page.has_content?('Sign in')
fill_in :user_email, :with => 'test#example.com'
fill_in :user_password, :with => 'testtest'
click_button('user_submit')
# ... because this test fails
assert page.has_content?('Signed in successfully.')
end
end
... but I have no idea why. As you can see from the code, the user is being created in the database; I'm using the same approach to create the user as I did in seeds.rb.
If I run the test through the debugger, I can see the user in the database and verify that the page is loading. But still the authentication fails; I can verify this because if I change the assertion to test for the failure case, the test passes:
# verify that the authentication actually failed
assert page.has_content?('Invalid email or password.')
I'm used to Rails 2, & using Selenium for this sort of testing, so I suspect I'm doing something daft. Could someone please point me in the right direction here?
I was having the same issue and found a thread with a solution:
RSpec.configure do |config|
config.use_transactional_fixtures = false
config.before(:suite) do
DatabaseCleaner.strategy = :truncation
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
end
For the DatabaseCleaner stuff to work you'll need to include the database_cleaner gem. If you haven't used it before, you may need to rake db:test:prepare before rerunning your tests. I hope this works for you, too!
I've run into a similar problem before. Setting the password directly has some weird effects because it's supposed to be encrypted and stored with a salt--sometimes it works for me and other times it doesn't. I have a hard time remembering which specific cases were problematic. I'd recommend the following, in this order (for simplicity)
Verify that the password field is getting filled in properly and passed as the right param (not necessary if you're using Devise's autogenerated view and haven't touched it)
if your site can run in development mode (i.e. no log in bugs), then just boot it up and log in manually
If not, insert debugger as the first line in your sessions_controller. Then check params and make sure the password is correct and in params[:user][:password].
If you didn't override Devise's sessions_controller, then you can find your Devise path with bundle show devise. Then look for the create action within (devise path)/app/controllers/devise/sessions_controller.rb
Change your test setup to create a user through the web interface, to ensure the password gets set properly, then try running your test again
I had the same issue with a setup fairly similar to yours. In my case, switching to ActiveRecord sessions in the initializer solved the problem.
Additionally, make sure you call #user.skip_confirmation! if you are using the "confirmable" module in devise.