Create a Ruby on Rails TODO application pt. 3

On with the test....

I found something the other day that I was not aware of.  A major major kudos to Jeffrey Way and his tutorial "The Intro to Rails Screencast I Wish I Had" which is the easiest to understand and best explanation of a Rails project creation and setup that I have seen.  I did not know that there was a Rails generator for integration_test.

After I created my app from the Rebel-Foundation clone, and did my bundle install, the next thing that I did was run 'rails g integration_test notes'.  This then created the notes_spec.rb file in the spec/requests directory.  I then cleaned out the mess and now my test looks like:

[sourcecode language="ruby"]
require 'spec_helper'
describe "Notes" do
it 'should be able to create a new note', js: true do
visit notes_path
click_link 'New Note'
fill_in 'Title', with: 'Clean out the Garage'
fill_in 'Description', with: 'Get rid of the junk and clean out the clutter'
fill_in 'Due by', with: '2/1/2012'
click_link 'Save'

page.should have_content 'Note created successfully'
page.should_not have_content 'Error'
end
end
[/sourcecode]

That was pretty easy to write seeing as we had this all listed in the story already.  Now it is easy to see that writing good stories is helpful for when you need to write the tests for them.

So with using Rspec and Capybara we can create the actual steps that the user wil need to take to create a note.  On line 05, I added the js: true so that Capybara will launch Firefox and use Selenium for our tests.  I don't think that this is really needed for this test as we are not using any Javascript but it is nice to see our efforts in the browser.

The first thing that we do is "visit notes_path", and then we follow the rest of the steps.  After clicking on 'Save' we EXPECT to see 'Note created successfully' on our page and not 'Error'.  When writing tests, think about what you are trying to do and what you expect to happen if you do that.  As we have not written any other code, we pretty much have a clean slate to work with.

[sourcecode language="bash"]
Failures:

1) Notes should be able to create a new note
Failure/Error: visit notes_path
NameError:
undefined local variable or method `notes_path' for #<RSpec::Core::ExampleGroup::Nested_1:0x007f8da8070458>
# ./spec/requests/notes_spec.rb:6:in `block (2 levels) in <top (required)>'

Finished in 22.4 seconds
1 example, 1 failure
[/sourcecode]

From here, we start down our path of sometimes absolutely useless error messages.  The issue here is not that there is not a variable or method but rather that there is not any routes created.  So we need to add "resources :notes" to our config/routes.rb file.  After adding that to our routes, we can run "rake routes" to see our RESTful routes:

[sourcecode language="bash"]
[master] ⚡$ rake routes
notes GET /notes(.:format) notes#index
POST /notes(.:format) notes#create
new_note GET /notes/new(.:format) notes#new
edit_note GET /notes/:id/edit(.:format) notes#edit
note GET /notes/:id(.:format) notes#show
PUT /notes/:id(.:format) notes#update
DELETE /notes/:id(.:format) notes#destroy
[/sourcecode]

With our Routes, we see that the index is notes. All we need to do to get to the index is add "_path" and we have "notes_path". We will also need to use the "new_note_path" when we go to create a new note. If we run our "rspec spec" test we now get:

[sourcecode language="bash"]
Failures:

1) Notes should be able to create a new note
Failure/Error: click_link 'New Note'
Capybara::ElementNotFound:
no link with title, id or text 'New Note' found
# (eval):2:in `click_link'
# ./spec/requests/notes_spec.rb:7:in `block (2 levels) in <top (required)>'

Finished in 19.59 seconds
1 example, 1 failure
[/sourcecode]

Well, at least this time we get an error message that make sense to us; there is no link 'New Note' for us to click on.  Sounds like a good thing to get into for our next post.

By the way, all of my code is available at git@github.com:brobertsaz/todo_application.git

comments powered by Disqus