Use Rspec and Capybara to test non Rails applications

Cristiano - July 22, 2015

I am a Ruby programmer, but sometimes I need to test the behaviour of non Ruby web applications.
In the last year I have developed over Social Engine, a social network developed using Zend framework.
After writing some code I want to test it, so I have searched a BDD framework for php but nothing is useful for me, also the truth is that I do not like php.
My tests are very basic, I want to compile a form with fake data and I want to test validations when the form is not well compiled, otherwise, if the form is well compiled and the validations are not triggered I want to test the redirection.
In some case, when the redirection works I want to test the database: it should have one more record. I know BDD is not useful to test database, but in this specific context, I am planning a custom solution.

You can checkout the Github repo of the project here

Gems

Plus rspec and capybara I use other useful gems:
Dotenv to manage the configuration of my project
Sequel to manage the persistance
Pry-rescue to debug my application when a test fail.

Dotenv

With this gem I configure the parameters of the entire application:

#.env
...
WEB_SERVER_URL = "http://localhost"
WEB_SERVER_ROOT_PATH = "/var/www/html" 

#edit this configuration to connect in your database
ADAPTER = "your-adapter"
USER = "your-user"
HOST = "your-host"
DATABASE = "your-database-name"
PASSWORD = "your-password"
...

Free feel to add or remove configurations.

Sequel

The connection with the database is managed with Sequel, an orm for ruby.

#sequel_config.rb
require 'sequel'
require 'dotenv'
Dotenv.load

DB = Sequel.connect(adapter: ENV['ADAPTER',],
                    user: ENV['USER'],
                    host: ENV['HOST'],
                    database: ENV['DATABASE'],
                    password: ENV['PASSWORD'])

The credentials and other configurations are read from the .env file

Then I have configured a model class to interact with the database:

#models/models.rb
#put your models here
#model example
...
class User < Sequel::Model(:users)
  set_primary_key :user_id
  one_to_many :members
end
...

You can see the Sequel docs for more info.

With this configuration I can type

$ irb                                                                                       
#remember to require the Sequel gem and the models.rb file
2.2.1 :001 > User.all.count 
=> 10

like Active Record.

Spec helper configuration

I am testing a non rack application, so I must configure the host and the driver for Capybara. I must also configure the browser to run the test.

#spec/spec_helper.rb

...
#use chrome or chromium instead the default firefox
if ENV["USE_CHROME_BROWSER"]
  Capybara.register_driver :selenium do |app|
    #provide a path for chrome 
    Selenium::WebDriver::Chrome.path = ENV["CHROME_PATH"] if ENV["CHROME_PATH"]
    Capybara::Selenium::Driver.new app, browser: :chrome
  end
end

#use the default :selenium driver if nothing is provided
if ENV['DRIVER']
  driver = ENV['DRIVER'].to_sym
else
  driver = :selenium
end

Capybara.default_driver = Capybara.javascript_driver = driver
Capybara.app_host = ENV['WEB_SERVER_URL']
...

With this configuration I can easily switch from Selenium to Webkit and from Firefox to Chrome.

Writing a test

#spec/features/create_user_spec.rb
feature 'create new User' do
 
  scenario 'with valid fields' do
    fill_in 'username', with: "A Username"
    fill_in 'password', with: "somePassword"
    
    #count the users before the submit
    users_before = User.all.count
    click_button 'submit'

    expect(current_url).to eq "http://localhost/my-redirect-url" 
    expect(User.all.count).to eq users_before + 1

  end
end

And then lunch the test with $ rspec spec/features/create_user_spec.rb.

Debug with Pry-rescue gem

When a test fail I want to inspect the variables. Whenever an exception is raised, but not rescued, pry-rescue will automatically open Pry for you. To proper configure the gem you can see the docs

To lunch a test with pry-rescue you can use the $ rescue rspec spec/features/create_user_spec.rb command.

Github

Free feel to checkout my Github repo