- Installed rvm (Ruby Version Manager). See Episode 200. Rails3 Beta and RVM
rupert:tsa rupert$ rvm ruby-1.9.2-p0
rupert:tsa rupert$ ruby -v
ruby 1.9.2p0 (2010-08-18 revision 29036) [x86_64-darwin10.5.0]
|
To use ruby-1.9.2-p0 as default
rupert:rails3 rupert$ rvm ruby-1.9.2-p0 --default
rupert:rails3 rupert$ ruby -v
ruby 1.9.2p0 (2010-08-18 revision 29036) [x86_64-darwin10.5.0]
|
- Install rails3
- Create a rails app tsa (the sample app)
- Start webrick. Yup, script/server is gone
rupert:tsa rupert$ rails server -e development
=> Booting WEBrick
=> Rails 3.0.3 application starting in production on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
[2010-12-06 20:47:27] INFO WEBrick 1.3.1
[2010-12-06 20:47:27] INFO ruby 1.9.2 (2010-08-18) [x86_64-darwin10.5.0]
[2010-12-06 20:47:27] INFO WEBrick::HTTPServer#start: pid=1348 port=3000
|
Note: Upon checking http://127.0.0.1:3000/ I get a “Routing Error”
- Update your GemFile with the necessary gems.
Let’s use devise as a login authentication system.
source 'http://rubygems.org'
gem 'rails', '3.0.3'
# Bundle edge Rails instead:
# gem 'rails', :git => 'git://github.com/rails/rails.git'
gem 'mysql2'
gem 'devise', :git => "git://github.com/plataformatec/devise.git", :branch => "master"
|
Then run bundle install. This will install devise gem.
rupert:tsa rupert$ bundle install
Fetching git://github.com/plataformatec/devise.git
remote: Counting objects: 10326, done.
remote: Compressing objects: 100% (3745/3745), done.
remote: Total 10326 (delta 6603), reused 9755 (delta 6163)
Receiving objects: 100% (10326/10326), 1.24 MiB | 314 KiB/s, done.
Resolving deltas: 100% (6603/6603), done.
Fetching source index for http://rubygems.org/
|
Where are the gems installed?
rupert:tsa rupert$ bundle show devise
/Users/rupert/.rvm/gems/ruby-1.9.2-p0/bundler/gems/devise-b50fd1a72e71
|
- Create the necessary databases in mysql. See config/database.yml
CREATE DATABASE tsa_development;
|
- Run devise generator.
rupert:tsa rupert$ rails generate devise:install
create config/initializers/devise.rb
create config/locales/devise.en.yml
===============================================================================
Some setup you must do manually if you havent yet:
1. Setup default url options for your specific environment. Here is an
example of development environment:
config.action_mailer.default_url_options = { :host => 'localhost:3000' }
This is a required Rails configuration. In production it must be the
actual host of your application
2. Ensure you have defined root_url to *something* in your config/routes.rb.
For example:
root :to => "home#index"
3. Ensure you have flash messages in app/views/layouts/application.html.erb.
For example:
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
===============================================================================
|
- Generate a controller in Rails3.
rupert:tsa rupert$ rails generate controller main index
create app/controllers/main_controller.rb
route get "main/index"
invoke erb
create app/views/main
create app/views/main/index.html.erb
invoke test_unit
create test/functional/main_controller_test.rb
invoke helper
create app/helpers/main_helper.rb
invoke test_unit
create test/unit/helpers/main_helper_test.rb
|
Update routes.rb for the root_url
- Create a User model with devise.
rupert:tsa rupert$ rails generate devise User
invoke active_record
create app/models/user.rb
invoke test_unit
create test/unit/user_test.rb
create test/fixtures/users.yml
create db/migrate/20101206104321_devise_create_users.rb
insert app/models/user.rb
route devise_for :users
rupert:tsa rupert$
|
- Run migration for User model
rupert:tsa rupert$ export RAILS_ENV=development
rupert:tsa rupert$ rake db:migrate
(in /Users/rupert/projects/rails3/tsa)
== DeviseCreateUsers: migrating ==============================================
-- create_table(:users)
-> 0.0805s
-- add_index(:users, :email, {:unique=>true})
-> 0.1368s
-- add_index(:users, :reset_password_token, {:unique=>true})
-> 0.1484s
== DeviseCreateUsers: migrated (0.3662s) =====================================
|
- Using cucumber
sudo port install libxml2 libxslt
|
- Update Gemfile
group :test, :development do
gem 'rspec'
gem 'rspec-rails'
gem 'cucumber'
gem 'cucumber-rails'
gem 'capybara'
gem 'launchy'
end
|
- Rspec
rupert:tsa rupert$ rails g rspec:install
create .rspec
create spec
create spec/spec_helper.rb
create autotest
create autotest/discover.rb
|
- Cucumber
rupert:tsa rupert$ rails g cucumber:install --rspec --capybara
create config/cucumber.yml
create script/cucumber
chmod script/cucumber
create features/step_definitions
create features/step_definitions/web_steps.rb
create features/support
create features/support/paths.rb
create features/support/env.rb
exist lib/tasks
create lib/tasks/cucumber.rake
gsub config/database.yml
gsub config/database.yml
force config/database.yml
|
- Write your first feature
Feature: Home Page
In order to make sure the home page works
As a normal user
I want to see the home page
Scenario: Show Main Sections
When I go to the home page
Then show me the page
Then I should see "Login"
|
From Harold Jimenez:
*“The Given step is where you set up the context of your scenario. Every scenario starts with a blank slate, so it is important to create a state in your application for example by creating data in the database, or by navigating to a specific page. </p>
The When step is where you exercise the application in order to accomplish what needs testing. In the case of a web app like twiddr, this is usually where you fill in forms, press buttons, click links, or otherwise interact with the system in some way.
Finally, the Then step is where you verify the result, and it’s where we check that the correct pages are rendered, that we see a success or error message, or anything that could help us verify that the prior action was successful. As we move along with creating our own features, this will become much clearer.”</em></blockquote>
- See it fail in cucumber
rake features (or)
cucumber (or)
bundle exec cucumber features/home.feature
|
rupert:tsa rupert$ cucumber
Using the default profile...
F--
(::) failed steps (::)
Can't find mapping from "the home page" to a path.
Now, go and add a mapping in /Users/rupert/projects/rails3/tsa/tsa/features/support/paths.rb (RuntimeError)
./features/support/paths.rb:26:in `rescue in path_to'
./features/support/paths.rb:20:in `path_to'
./features/step_definitions/web_steps.rb:24:in `/^(?:|I )go to (.+)$/'
features/home.feature:7:in `When I go to the home page'
Failing Scenarios:
cucumber features/home.feature:6 # Scenario: Show Main Sections
1 scenario (1 failed)
3 steps (1 failed, 2 skipped)
0m0.062s
|
- Defining “the home page” in the support/paths.rb
when /the home page/
root_path
|
and in the routes.rb
Other examples:
when /the profile page for "([^\"]+)"/
user = User.find_by_twiddr_name!($1)
user_path(user)
|
Note: When you see the error
undefined local variable or method `node' for #<Capybara::Driver::RackTest::Node:0x00000101151ad8> (NameError)"
|
You need to comment in features/support/env.rb
#require 'cucumber/rails/capybara_javascript_emulation'
|
For more info, read https://rspec.lighthouseapp.com/projects/16211-cucumber/tickets/674
- Then show me the page will open up the browser
file://localhost/Users/rupert/projects/rails3/tsa/tsa/tmp/capybara/capybara-20101209222149.html
|
- Automatic Testing with “autotest”. When you save a file, autotest automatically runs cucumber. To avoid autotest infinite loop with cucumber, make sure your IDE (i.e rubymine) does not save automatically in the file system. You can exclude files and directories from autotest with a “.autotest” file
Autotest.add_hook :initialize do |at|
at.add_exception(%r{^\./\.git})
at.add_exception(%r{^\./db})
at.add_exception(%r{^\./log})
at.add_exception(%r{^\./tmp})
at.add_exception(%r{^\./.idea})
at.add_exception(%r{^\./rerun\.txt})
at.add_exception(%r{^\./Gemfile\.lock})
end
|
Now you can run, autotest from the terminal. Save a file and see autotest run.
- If you have javascript AJAX calls included in cucumber scenarios, you need to append them with @javascript tag. Below is a sample which selects “Australia” from the “Country” and waits for the ajax request to finish before selecting the “State” drop down. More info on capybara github.
@javascript
Scenario: Creating a Fleet
And I select "Australia" from "Country"
And I wait for the ajax request to finish
And I select "Victoria" from "State"
|
How does the step “I wait for the ajax request to finish” looks like? http://stackoverflow.com/questions/7286254/cucumber-wait-for-ajaxsuccess
When /^I wait for the ajax request to finish$/ do
start_time = Time.now
page.evaluate_script('jQuery.isReady&&jQuery.active==0').class.should_not eql(String) until page.evaluate_script('jQuery.isReady&&jQuery.active==0') or (start_time + 5.seconds) < Time.now
sleep 1
end
end
|