codedecoder

breaking into the unknown…


2 Comments

sample app with sinatra rspec capybara and selenium

I have been working with rails rspec capybara and selenium for long, but recently I have to build an API for client which he specifically requested in sinatra. I will list difference between rails and sinatra some other days. For now, I can quote below characteristic for sinatra

1->It not a framework i,e no folder , configuration file etc get created
2->no mvc concept, whole project may be written in a single file
3->can pack your app as a gem which can be used by other . ex : resque for managing background job is build on sinatra

You can download a no of available ebook on sinatra to know it in detail. Here, I will just create a “Hello sinatra” app and configure it with rspec capybara and selenium. STEPS 1 to 6 is just the basic steps Iam following in all the rails project as so adopted it here also a good practice

STEP 1: create your project folder and call it say sinatra_app

STEP 2: create a gemset sinatra_app if you are using RVM(I suggest all ruby dveloper to use it ) # detail on RVM is avilable here and here

If you are not using RVM, install bundler gem first with the command sudo gem install bundler. more detail on bundler is available here

STEP 3: create a file with name Gemfile in this folder and add the required gems to it. The Gemfile content will look like this

source 'https://rubygems.org'

gem "thin" # sinatra by default run with thin, so this gem is also required
gem "sinatra"

group :test do
  gem "rspec", ">= 1.2.1"
  gem "capybara", ">= 1.1.2"
end

STEP 4: If you are using RVM create a .rvmrc file in your sinatra_app folder and add below line to it.

It will load the proper ruby version and your sinatra_app gemset everytime you cd to the sinatra_app folder

rvm ruby-1.9.3-p194@sinatra_app # Iam assuming that you are using ruby version rvm ruby-1.9.3-p194 and your gemset name is sinatra_app, change it accordingly

STEP 5 : go to terminal and cd to sinatra_app folder and run below command

$ bundle install # you will slow below trace on the terminal
Fetching gem metadata from https://rubygems.org/.........
Fetching gem metadata from https://rubygems.org/..
Using addressable (2.3.2) 
Using mime-types (1.19) 
Installing nokogiri (1.5.6) with native extensions 
Installing rack (1.4.3) 
Using rack-test (0.6.2) 
Installing ffi (1.3.0) with native extensions 
Installing childprocess (0.3.6) 
Installing websocket (1.0.6) 
Installing libwebsocket (0.1.7.1) 
Installing multi_json (1.5.0) 
Using rubyzip (0.9.9) 
Installing selenium-webdriver (2.27.2) 
Installing xpath (1.0.0) 
Installing capybara (2.0.2) 
Using daemons (1.1.9) 
Using diff-lcs (1.1.3) 
Using eventmachine (1.0.0) 
Using rack-protection (1.3.2) 
Installing rspec-core (2.12.2) 
Installing rspec-expectations (2.12.1) 
Installing rspec-mocks (2.12.1) 
Installing rspec (2.12.0) 
Using tilt (1.3.3) 
Using sinatra (1.3.3) 
Installing thin (1.5.0) with native extensions 
Using bundler (1.1.5)

Thus you can see that all our required gem thin, rspec,and  capybara get installed along with there dependency. You can also see a new file Gemfile.lock get created in sinatra_app folder. Since, our base is now ready, so better push our code to git in the next step

STEP 6 : pushing the existing files to GIT

$ cd sinatra_app #all mentioned command here will run only after moving to sinatra_app folder
$ git init .
$ git add .
$ git commit -a -m"my initial commit"

STEP 7: create my_sinatra_app.rb file and below line to it

require 'sinatra'
get '/' do
  "Hello....Sinatra :)"
end

STEP 8: Run the app on terminal with ruby command

$ ruby loanpath_api.rb
== Sinatra/1.3.3 has taken the stage on 4567 for development with backup from Thin
>> Thin web server (v1.3.1 codename Triple Espresso)
>> Maximum connections set to 1024
>> Listening on 0.0.0.0:4567, CTRL+C to stop

You can see that thin is Listining to port 4567 at 0.0.0.0

STEP 9: see your app in browser by typing 0.0.0.0:4567 #you can see the loaded page with message “Hello….Sinatra :)”

STEP 10: Adding rspec to sinatra

$ rspec --init
The --configure option no longer needs any arguments, so true was ignored.
  create   spec/spec_helper.rb
  create   .rspec

You can see that it has created two files for you within spec folder. The important one is spec_helper.rb. The default content of this file is as below

RSpec.configure do |config|
  config.treat_symbols_as_metadata_keys_with_true_values = true
  config.run_all_when_everything_filtered = true
  config.filter_run :focus
  config.order = 'random'
end

we will add, the require configuration to make rspec work with sinatra in the next step. Infact, any rspec configuration should go to this file.

STEP 11 : spec_helper.rb content after adding setting for sinatra is as below

require 'rack/test' # it is needed to run rspec
include Rack::Test::Methods # It contain different method like get,  last_response etc which
 you use to write your test

def app
  Sinatra::Application # It is must and tell rspec that test it running is for sinatra
end

set :environment, :test # setting the environment in which the test will run

RSpec.configure do |config|
  config.treat_symbols_as_metadata_keys_with_true_values = true
  config.run_all_when_everything_filtered = true
  config.filter_run :focus
  config.order = 'random'
end

STEP 12 : Writing the first test case
create a file with any name, but as a good practice, it should be same as the file you are testing so we will call it my_sinatra_app_specs.rb and add below line to it

require_relative '../my_sinatra_app.rb' # this load the file you are testing
require 'spec_helper.rb' # It will load the configuration you set in spec_helper.rb

describe 'sinatra app home page' do	
	it "should load the home page" do # the first test
	  get '/' # you are visiting the home page
	  last_response.should be_ok # it will true if the home page load successfully
	end
end

STEP 13 : Run test file my_sinatra_app_specs.rb with rspec

$ rspec spec/my_sinatra_app_specs.rb
Run options: include {:focus=>true}

All examples were filtered out; ignoring {:focus=>true}
.

Finished in 0.01908 seconds
1 example, 0 failures

Randomized with seed 28600

Thus, you can see that, our test has pass. till now we are using methods available to rspec, if you want to use methods like visit, response etc it will throw error as they are methods of capybara which we have still not configured. we will configure capybara and selenium in next step and then modify our test to use visit and response instead of get and last_reponse

STEP 14 : configuring rspec to work with capybara and selenium

Since, now we are going to use capybara, we do not need get, last_rsponse etc method of  Rack::Test::Methods, so we will remove the top two line and replace them with capybara configuration. The spec_helper.rb will now look as below. You can read more about capybara here

require 'capybara' # loading capybara
include Capybara::DSL # It contain all the methods you use for writing test. If you do not use it , 
get this error.
Capybara.default_driver = :selenium # it will tell capybara to use selenium. It should be noted that  
By default, Capybara uses the :rack_test driver, which is fast but limited: it does not support 
JavaScript, nor is it able to access HTTP resources outside of your Rack application, such as remote 
APIs and OAuth services.

def app 
  Sinatra::Application 
end 

set :environment, :test 
RSpec.configure do |config| 
  config.treat_symbols_as_metadata_keys_with_true_values = true 
  config.run_all_when_everything_filtered = true 
  config.filter_run :focus config.order = 'random' 
end

STEP 15 : modifying our test case

We will now rewrite, our test case in steps 12 with capybara methods like visit ,page etc

describe 'make API call to loanpath' do	
  it "should load the home page" do
    visit 'http://0.0.0.0:4567'
    page.should have_content("sinatra")
  end
end

Now, when you run your test again with rspec spec/my_sinatra_app_specs.rb command, you can see capybara working and selenium web driver simulating your app