Skip to content
Sinatra App to demo: Sinatra, Cucumber, RSpec, Haml, Sass, Webrat, Nokogiri http://svrailsconf.heroku.com
Ruby
Find file
Pull request Compare This branch is 1 commit ahead of bikle:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.
features
public
spec
views
README.rdoc
app.rb
config.ru

README.rdoc

svrailsconf

svrailsconf is a Sinatra App which demonstrates how to attach both Cucumber and RSpec tests to a Sinatra App. Also svrailsconf makes use of these common gems: Haml, Sass, Webrat, and Nokogiri.

If you are new to Sinatra but familiar with Rails then installation of this app should be easy.

First, install these gems:

Sun May 23 13:41 /pt/b/sinatra/svrailsconf maco$ 
Sun May 23 13:41 /pt/b/sinatra/svrailsconf maco$ 
Sun May 23 13:41 /pt/b/sinatra/svrailsconf maco$ 
Sun May 23 13:41 /pt/b/sinatra/svrailsconf maco$ gem list

*** LOCAL GEMS ***

builder (2.1.2)
columnize (0.3.1)
configuration (1.1.0)
cucumber (0.7.3)
diff-lcs (1.1.2)
gherkin (1.0.30)
haml (3.0.4)
heroku (1.9.9)
json_pure (1.4.3)
launchy (0.3.5)
linecache (0.43)
mime-types (1.16)
nokogiri (1.4.2)
rack (1.1.0)
rack-test (0.5.3)
rake (0.8.7)
rest-client (1.4.2)
rspec (1.3.0)
ruby-debug (0.10.3)
ruby-debug-base (0.10.3)
sinatra (1.0)
term-ansicolor (1.0.5)
trollop (1.16.2)
webrat (0.7.1)
Sun May 23 13:41 /pt/b/sinatra/svrailsconf maco$ 
Sun May 23 13:41 /pt/b/sinatra/svrailsconf maco$ 
Sun May 23 13:41 /pt/b/sinatra/svrailsconf maco$

Next, obtain svrailsconf from github:

Sun May 23 13:46 /software maco$ 
Sun May 23 13:46 /software maco$ cd /tmp
Sun May 23 13:46 /tmp maco$ 
Sun May 23 13:46 /tmp maco$ 
Sun May 23 13:46 /tmp maco$   git clone git@github.com:bikle/svrailsconf.git
Initialized empty Git repository in /private/tmp/svrailsconf/.git/
remote: Counting objects: 32, done.        
remote: Compressing objects: 100% (26/26), done.        
remote: Total 32 (delta 2), reused 0 (delta 0)        
Receiving objects: 100% (32/32), 29.96 KiB, done.
Resolving deltas: 100% (2/2), done.
Sun May 23 13:46 /tmp maco$ 
Sun May 23 13:46 /tmp maco$ 
Sun May 23 13:46 /tmp maco$

Then, start it up:

Sun May 23 13:56 /tmp/svrailsconf maco$ 
Sun May 23 13:56 /tmp/svrailsconf maco$ cd /tmp
Sun May 23 13:56 /tmp maco$ 
Sun May 23 13:56 /tmp maco$ cd svrailsconf
Sun May 23 13:56 /tmp/svrailsconf maco$ 
Sun May 23 13:56 /tmp/svrailsconf maco$ 
Sun May 23 13:56 /tmp/svrailsconf maco$ 
Sun May 23 13:56 /tmp/svrailsconf maco$ ll
total 24
drwxr-xr-x  10 maco  wheel   340 May 23 13:46 ./
drwxrwxrwt  22 root  wheel   748 May 23 13:46 ../
drwxr-xr-x  13 maco  wheel   442 May 23 13:46 .git/
-rw-r--r--   1 maco  wheel  1194 May 23 13:46 README.rdoc
-rw-r--r--   1 maco  wheel   590 May 23 13:46 app.rb
-rw-r--r--   1 maco  wheel    42 May 23 13:46 config.ru
drwxr-xr-x   5 maco  wheel   170 May 23 13:46 features/
drwxr-xr-x   4 maco  wheel   136 May 23 13:46 public/
drwxr-xr-x   4 maco  wheel   136 May 23 13:46 spec/
drwxr-xr-x  10 maco  wheel   340 May 23 13:46 views/
Sun May 23 13:56 /tmp/svrailsconf maco$ 
Sun May 23 13:56 /tmp/svrailsconf maco$ 
Sun May 23 13:56 /tmp/svrailsconf maco$ ruby app.rb
== Sinatra/1.0 has taken the stage on 4567 for development with backup from WEBrick
[2010-05-23 13:57:04] INFO  WEBrick 1.3.1
[2010-05-23 13:57:04] INFO  ruby 1.8.7 (2009-06-12) [i686-darwin9.8.0]
[2010-05-23 13:57:04] INFO  WEBrick::HTTPServer#start: pid=5257 port=4567

And you should see something like this:

http://github.com/bikle/svrailsconf/blob/master/public/images/svrailsconf.png

If you cannot get it to run on your laptop, perhaps you can deploy it to heroku. Here is a demonstration of that idea:

Sun May 23 14:21 /tmp/svrailsconf maco$ 
Sun May 23 14:21 /tmp/svrailsconf maco$ 
Sun May 23 14:22 /tmp/svrailsconf maco$ ssh-add -D
All identities removed.
Sun May 23 14:22 /tmp/svrailsconf maco$ 
Sun May 23 14:22 /tmp/svrailsconf maco$ ssh-add /pt/b/sinatra/ssh_key.txt
Identity added: /pt/b/sinatra/ssh_key.txt (/pt/b/sinatra/ssh_key.txt)
Sun May 23 14:23 /tmp/svrailsconf maco$ 
Sun May 23 14:23 /tmp/svrailsconf maco$ heroku create svrc2010_0523
 !   Name must start with a letter and can only contain letters, numbers, and dashes
Sun May 23 14:24 /tmp/svrailsconf maco$ heroku create svrc20100523
Creating svrc20100523..... done
Created http://svrc20100523.heroku.com/ | git@heroku.com:svrc20100523.git
Git remote heroku added
Sun May 23 14:24 /tmp/svrailsconf maco$ 
Sun May 23 14:24 /tmp/svrailsconf maco$ 
Sun May 23 14:24 /tmp/svrailsconf maco$ 

Sun May 23 14:24 /tmp/svrailsconf maco$ 
Sun May 23 14:24 /tmp/svrailsconf maco$ 
Sun May 23 14:24 /tmp/svrailsconf maco$ 
Sun May 23 14:24 /tmp/svrailsconf maco$ git push heroku master
Counting objects: 32, done.
Compressing objects: 100% (24/24), done.
Writing objects: 100% (32/32), 29.99 KiB, done.
Total 32 (delta 2), reused 32 (delta 2)

-----> Heroku receiving push
-----> Sinatra app detected
       Compiled slug size is 32K
-----> Launching..... done
       http://svrc20100523.heroku.com deployed to Heroku

To git@heroku.com:svrc20100523.git
 * [new branch]      master -> master
Sun May 23 14:24 /tmp/svrailsconf maco$ 
Sun May 23 14:24 /tmp/svrailsconf maco$ 
Sun May 23 14:24 /tmp/svrailsconf maco$ 

Sun May 23 14:24 /tmp/svrailsconf maco$ 
Sun May 23 14:24 /tmp/svrailsconf maco$ 
Sun May 23 14:24 /tmp/svrailsconf maco$ 
Sun May 23 14:24 /tmp/svrailsconf maco$ curl http://svrc20100523.heroku.com -o /tmp/my.html
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1101  100  1101    0     0   3567      0 --:--:-- --:--:-- --:--:--     0
Sun May 23 14:25 /tmp/svrailsconf maco$ 
Sun May 23 14:25 /tmp/svrailsconf maco$ 
Sun May 23 14:25 /tmp/svrailsconf maco$ 
Sun May 23 14:25 /tmp/svrailsconf maco$ 

Sun May 23 14:25 /tmp/svrailsconf maco$ 
Sun May 23 14:25 /tmp/svrailsconf maco$ 
Sun May 23 14:25 /tmp/svrailsconf maco$ 
Sun May 23 14:25 /tmp/svrailsconf maco$ 
Sun May 23 14:25 /tmp/svrailsconf maco$ head -6 /tmp/my.html 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang='en-US' xml:lang='en-US' xmlns='http://www.w3.org/1999/xhtml'>
  <head>
    <title>SV Ruby Conf 2010</title>
  </head>
  <body>
Sun May 23 14:26 /tmp/svrailsconf maco$ 
Sun May 23 14:26 /tmp/svrailsconf maco$ 
Sun May 23 14:26 /tmp/svrailsconf maco$ 
Sun May 23 14:26 /tmp/svrailsconf maco$

If you want to learn how to write Cucumber tests for Sinatra Apps, perhaps svrailsconf will be useful. I demonstrate the running of Cucumber tests which have already been written.

First I check that I have the Cucumber gem installed:

Sun May 23 15:48 /tmp/svrailsconf maco$ 
Sun May 23 15:48 /tmp/svrailsconf maco$ 
Sun May 23 15:48 /tmp/svrailsconf maco$ gem list cucumber

*** LOCAL GEMS ***

cucumber (0.7.3)
Sun May 23 15:49 /tmp/svrailsconf maco$ 
Sun May 23 15:49 /tmp/svrailsconf maco$ 
Sun May 23 15:49 /tmp/svrailsconf maco$

Next, I check that the cucumber command is in my PATH:

Sun May 23 15:49 /tmp/svrailsconf maco$ 
Sun May 23 15:49 /tmp/svrailsconf maco$ 
Sun May 23 15:49 /tmp/svrailsconf maco$ which cucumber
/Users/maco/.rvm/gems/ruby-1.8.7-p174%sinatra/bin/cucumber
Sun May 23 15:49 /tmp/svrailsconf maco$ 
Sun May 23 15:49 /tmp/svrailsconf maco$ 
Sun May 23 15:49 /tmp/svrailsconf maco$

Cucumber runs tests controlled by Gherkin which is a language (written by product managers hopefully) inside files with the suffix “feature”. A file named “hello.feature” is listed below:

Sun May 23 15:49 /tmp/svrailsconf maco$ 
Sun May 23 15:49 /tmp/svrailsconf maco$ 
Sun May 23 15:49 /tmp/svrailsconf maco$ ll features/
total 8
drwxr-xr-x   5 maco  wheel  170 May 23 13:46 ./
drwxr-xr-x  11 maco  wheel  374 May 23 15:47 ../
-rw-r--r--   1 maco  wheel  346 May 23 13:46 hello.feature
drwxr-xr-x   3 maco  wheel  102 May 23 13:46 step_definitions/
drwxr-xr-x   3 maco  wheel  102 May 23 13:46 support/
Sun May 23 15:49 /tmp/svrailsconf maco$ 
Sun May 23 15:49 /tmp/svrailsconf maco$ 
Sun May 23 15:49 /tmp/svrailsconf maco$ cat features/hello.feature 
Feature: See Homepage
  In order to verify loading of homepage
  As Dan
  I want to see the homepage

  Scenario: Load the homepage
    Given That I am "Dan"
    When I am on the homepage
    Then I should see "SV Rails Conf"
    And I should see the png: svtrain.png
    And On LHS I should see links: "Home Program Venue Speakers Registration"
Sun May 23 15:49 /tmp/svrailsconf maco$ 
Sun May 23 15:49 /tmp/svrailsconf maco$

We can see that the language of Gherkin is very simple when compared to a computer language like Ruby or JavaScript. The author of Cucumber intends that you ask the Product Manager of your app to write the Gherkin inside of “feature” files.

After I wrote hello.feature, I wanted it to “drive” my app. I see this as like a robot connecting to the app and my hello.feature file controls the robot. The way this is implemented is the Gherkin syntax in hello.feature needs to get translated into Ruby syntax. Once the translation is done, the Ruby syntax is the thing which drives the app.

For example I could have this Gherkin command:

When I am on the homepage

As a Cucumber “expert” I know that the above command needs to get translated to this Ruby command:

@rspns= get "/"

So a key idea there is that if you want to use Cucumber to test your apps you need to know how to translate Gherkin into Ruby. One thing which helps you is that you are not writing low-level Ruby; you are writing Ruby which makes calls to APIs which are powerful yet simple.

Another idea to understand is that translation from Gherkin to Ruby requires that you have a mechanism to map each Gherkin statement to some Ruby code.

You can see how this is done if you study this file:

github.com/bikle/svrailsconf/blob/master/features/step_definitions/some_steps.rb

The above file suggests that if we want to map this Gherkin command:

When I am on the homepage

To this Ruby command:

@rspns= get "/"

Then we need to have some syntax like this in some_steps.rb:

When /^I am on the homepage$/ do
  @rspns= get "/"
end

As you gain experience with Cucumber, Gherkin, and the API calls resident within the features/step_definitions/ files, your Ruby syntax will become more thorough at testing your app.

You can see that by studying the Ruby syntax which is derived from the Gherkin command:

When I am on the homepage

So, here is some information about how I have translated Gherkin into Ruby for this app:

Sun May 23 15:49 /tmp/svrailsconf maco$ 
Sun May 23 15:49 /tmp/svrailsconf maco$ 
Sun May 23 15:49 /tmp/svrailsconf maco$ 
Sun May 23 15:49 /tmp/svrailsconf maco$ ll features/step_definitions/
total 8
drwxr-xr-x  3 maco  wheel   102 May 23 13:46 ./
drwxr-xr-x  5 maco  wheel   170 May 23 13:46 ../
-rw-r--r--  1 maco  wheel  1238 May 23 13:46 some_steps.rb
Sun May 23 15:49 /tmp/svrailsconf maco$ 
Sun May 23 15:49 /tmp/svrailsconf maco$ 
Sun May 23 15:49 /tmp/svrailsconf maco$ cat features/step_definitions/some_steps.rb 

Given /^That I am "([^\"]*)"$/ do |arg1|
  # Anyone will make this test pass
end

When /^I am on the homepage$/ do
  # Here is the Nokogiri way:
  @rspns= get "/"
  @ndoc= Nokogiri::HTML(@rspns.body)
  # Here is the webrat way:
  visit "/"
end

Then /^I should see "([^\"]*)"$/ do |arg1|
  # @ndoc.css("h1")[0].content.should match /Haml on Sinatra Example/
  @ndoc.css("h1")[0].content.should match(Regexp.new(arg1))

  # Here is the webrat way:
  last_response.should contain(arg1)
  last_response.should have_selector("div#header h1")
  last_response.should have_xpath("//body/table/tr/td/div[@id='header']/h1")
end

Then /^I should see the png: svtrain\.png$/ do
  # Here is the Nokogiri way:
  @ndoc.xpath("//img[@id='svtrain']/@src")[0].value.should== "/images/svtrain.png"
  # Here is the webrat way:
  last_response.should have_selector("body table tr td img#svtrain")
  last_response.should have_xpath("//body/table/tr/td/img[@id='svtrain'][@src='/images/svtrain.png']")
end

Then /^On LHS I should see links: "([^\"]*)"$/ do |arg1|
  links_from_dot_feature= arg1.split
  lhs_links_from_page= @ndoc.css("table tr#tr_two td#td_lhs a").map{ |ae| ae.content}
  lhs_links_from_page.sort.should== links_from_dot_feature.sort
end

Sun May 23 15:49 /tmp/svrailsconf maco$ 
Sun May 23 15:49 /tmp/svrailsconf maco$ 
Sun May 23 15:49 /tmp/svrailsconf maco$

If you are an experienced programmer, you will see that I am using code which makes API calls dependent on these APIs and technologies:

Nokogiri

Webrat

RSpec

Regular_Expressions

CSS

XPath

So, now that I have described my understanding of Cucumber, how do we actually run a Cucumber test? The screen-dump below demonstrates how to run a Cucumber test:

Sun May 23 17:16 /tmp/svrailsconf maco$ 
Sun May 23 17:16 /tmp/svrailsconf maco$ gem list cucumber

*** LOCAL GEMS ***

cucumber (0.7.3)
Sun May 23 17:16 /tmp/svrailsconf maco$ 
Sun May 23 17:16 /tmp/svrailsconf maco$ which cucumber
/Users/maco/.rvm/gems/ruby-1.8.7-p174%sinatra/bin/cucumber
Sun May 23 17:17 /tmp/svrailsconf maco$ 
Sun May 23 17:17 /tmp/svrailsconf maco$ 
Sun May 23 17:17 /tmp/svrailsconf maco$ cucumber features/hello.feature 
Feature: See Homepage
  In order to verify loading of homepage
  As Dan
  I want to see the homepage

  Scenario: Load the homepage                                                 # features/hello.feature:6
    Given That I am "Dan"                                                     # features/step_definitions/some_steps.rb:2
    When I am on the homepage                                                 # features/step_definitions/some_steps.rb:6
    Then I should see "SV Rails Conf"                                         # features/step_definitions/some_steps.rb:14
    And I should see the png: svtrain.png                                     # features/step_definitions/some_steps.rb:24
    And On LHS I should see links: "Home Program Venue Speakers Registration" # features/step_definitions/some_steps.rb:33

1 scenario (1 passed)
5 steps (5 passed)
0m0.052s
Sun May 23 17:17 /tmp/svrailsconf maco$

Suppose that your app has no product manager. Perhaps your app only has you and that you are the developer? In that case if the app is simple it might make sense to test your app only with RSpec. When you test an app with RSpec the tests are written in Ruby. Unlike Cucumber, with RSpec you do not need to write step_definition files to translate Gherkin into Ruby.

Here is the URL to the RSpec file I wrote to test this app:

github.com/bikle/svrailsconf/blob/master/spec/app_spec.rb

When you study syntax in the above RSpec file and compare it to Gherkin and Ruby syntax in the Cucumber related files, it should be obvious that writing tests in RSpec is easier.

A screen dump of the syntax to run the RSpec tests is displayed below:

Sun May 23 17:54 /pt/b/sinatra/svrailsconf maco$ 
Sun May 23 17:54 /pt/b/sinatra/svrailsconf maco$ 
Sun May 23 17:54 /pt/b/sinatra/svrailsconf maco$ 
Sun May 23 17:54 /pt/b/sinatra/svrailsconf maco$ gem list rspec

*** LOCAL GEMS ***

rspec (1.3.0)
Sun May 23 17:55 /pt/b/sinatra/svrailsconf maco$ 
Sun May 23 17:55 /pt/b/sinatra/svrailsconf maco$ 

Sun May 23 17:55 /pt/b/sinatra/svrailsconf maco$ 
Sun May 23 17:55 /pt/b/sinatra/svrailsconf maco$ which spec
/Users/maco/.rvm/gems/ruby-1.8.7-p174%sinatra/bin/spec
Sun May 23 17:55 /pt/b/sinatra/svrailsconf maco$ 
Sun May 23 17:55 /pt/b/sinatra/svrailsconf maco$ 
Sun May 23 17:55 /pt/b/sinatra/svrailsconf maco$ 

Sun May 23 17:55 /pt/b/sinatra/svrailsconf maco$ 
Sun May 23 17:55 /pt/b/sinatra/svrailsconf maco$ 
Sun May 23 17:55 /pt/b/sinatra/svrailsconf maco$ 
Sun May 23 17:55 /pt/b/sinatra/svrailsconf maco$ spec spec/app_spec.rb
...

Finished in 0.017241 seconds

3 examples, 0 failures
Sun May 23 17:55 /pt/b/sinatra/svrailsconf maco$ 
Sun May 23 17:55 /pt/b/sinatra/svrailsconf maco$ 
Sun May 23 17:55 /pt/b/sinatra/svrailsconf maco$

Perhaps it should be noted that the name of the gem is “rspec”, the name of the executable is “spec” and the directory which holds the RSpec file(s) is “spec”.

Something went wrong with that request. Please try again.