Warning & disclaimer
This gem is currently under development. We're targeting most popular use cases - Rails & Rack applications (ex. Sinatra). However the philosophy behind it is not limited to Rails nor web applications in general. There is even example usage with EventMachine. Feel free to modify it for your own needs.
BBQ
Object oriented acceptance testing using personas.
- Ruby
- OOP
- DCI (Data Context Interaction) - for roles/personas
- Test framework independent, based on Capybara
- Opinionated
Difference from Cucumber
- No Gherkin
- Objects and methods instead of steps
- Easier code reuse
- No factories/fixtures
Example applications
Related examples
Installation
First, add BBQ to your apps Gemfile:
# Gemfile
gem "bbq", :git => "git://github.com/drugpl/bbq"
Run install generator:
rails generate bbq:install
Require BBQ in test/test_helper.rb (in case of Test::Unit):
require "bbq/test_unit"
Require BBQ in spec/spec_helper.rb (in case of RSpec):
require "bbq/rspec"
Feature generator
rails g bbq:test MyFeatureName
Running features
For Test::Unit flavour:
rake test:acceptance
For RSpec flavour:
spec:acceptance
Examples
module Roundtrip
class TestUser < Bbq::TestUser
include Bbq::Devise
def update_ticket(summary, comment)
show_ticket(summary)
fill_in "Comment", :with => comment
click_on "Add update"
end
def open_application
visit '/'
end
module TicketReporter
def open_tickets_listing
open_application
click_link 'Tickets'
end
def open_ticket(summary, description)
open_tickets_listing
click_on "Open a new ticket"
fill_in "Summary", :with => summary
fill_in "Description", :with => description
click_on "Open ticket"
end
def show_ticket(summary)
open_tickets_listing
click_on summary
end
end
module TicketManager
def open_administration
visit '/admin'
end
def open_tickets_listing
open_administration
click_link 'Tickets'
end
def close_ticket(summary, comment = nil)
open_tickets_listing
click_on summary
fill_in "Comment", :with => comment if comment
click_on "Close ticket"
end
def show_ticket(summary)
open_tickets_listing
click_on summary
end
end
end
end
class AdminTicketsTest < Bbq::TestCase
background do
admin = Factory(:admin)
@email, @password = admin.email, admin.password
end
scenario "admin can browse all user tickets" do
summaries = ["Forgot my password", "Page is not displayed correctly"]
descriptions = ["I lost my yellow note with password under the table!",
"My IE renders crap instead of crispy fonts!"]
alice = Roundtrip::TestUser.new
alice.roles(:ticket_reporter)
alice.register_and_login
alice.open_ticket(summaries.first, descriptions.first)
bob = Roundtrip::TestUser.new
bob.roles(:ticket_reporter)
bob.register_and_login
bob.open_ticket(summaries.second, descriptions.second)
charlie = Roundtrip::TestUser.new(:email => @email, :password => @password)
charlie.login # charlie was already "registered" in factory as admin
charlie.roles(:ticket_manager)
charlie.open_tickets_listing
charlie.see!(*summaries)
charlie.click_on(summaries.second)
charlie.see!(summaries.second, descriptions.second)
charlie.not_see!(summaries.first, descriptions.first)
end
end
Testing REST APIs
Bbq provides Bbq::TestClient
, similar to Bbq::TestUser
, but intended for testing APIs.
It's a thin wrapper around Rack::Test
which allows you to send requests and run assertions
against responses.
class ApiTest < Bbq::TestCase
background do
headers = {'HTTP_ACCEPT' => 'application/json'}
@client = TestClient.new(:headers => headers)
end
scenario "admin can browse all user tickets" do
@client.get "/unicorn" do |response|
assert_equal 200, response.status
assert_equal "pink", response.body["unicorn"]["color"]
end
@client.post "/ponies", { :name => "Miracle" } do |response|
assert_equal 200, response.status
end
end
end
Rails' URL Helpers
Using url helpers from Rails in integration tests is not recommended. Testing routes is part of integration test, so you should actually use only
visit '/'
in your integration test. Use links and buttons in order to get to other pages in your app.
If you really need url helpers in your test user, just include them in your TestUser class:
require 'bbq/rails/routes'
module Roundtrip
class TestUser < Bbq::TestUser
include Bbq::Rails::Routes
end
end
or just
module Roundtrip
class TestUser < Bbq::TestUser
include ::ActionDispatch::Routing::UrlFor
include ::Rails.application.routes.url_helpers
include ::ActionDispatch::Routing::RouteSet::MountedHelpers unless ::Rails.version < "3.1"
end
end
Deal with Devise
require "bbq/test_user"
require "bbq/devise"
class TestUser < Bbq::TestUser
include Bbq::Devise
end
After that TestUser have login, logout, register, register_and_login methods.
test "user register with devise" do
user = TestUser.new # or TestUser.new(:email => "[email protected]", :password => "secret")
user.register_and_login
user.see!("Stuff after auth")
end
Caveats
Timeout::Error
If you simulate multiple users in your tests and spawn multiple browsers with selenium it might
be a good idea to use Thin instead of Webrick to create application server.
We have experienced some problems with Webrick that lead to Timeout::Error
exception
when user/browser that was inactive for some time (due to other users/browsers
activities) was requested to execute an action.
Capybara will use Thin instead of Webrick when it's available, so you only need to add Thin to you Gemfile:
# In test group if you want it to
# be used only in tests and not in your development mode
# ex. when running 'rails s'
gem 'thin', :require => false
Development environment
bundle install
bundle exec rake test
Additional information
- 2 problems with Cucumber http://andrzejonsoftware.blogspot.com/2011/03/2-problems-with-cucumber.html
- Object oriented acceptance testing http://andrzejonsoftware.blogspot.com/2011/04/object-oriented-acceptance-testing.html
- Events in acceptance tests http://andrzejonsoftware.blogspot.com/2011/04/events-in-acceptance-tests.html
Maintainers
- Paweł Pacana (http://github.com/pawelpacana)
- Andrzej Krzywda (http://andrzejkrzywda.com)
- Michał Łomnicki (http://mlomnicki.com)
- Robert Pankowecki (http://robert.pankowecki.pl)
Contributors
- Piotr Niełacny (http://ruby-blog.pl)
- Peter Suschlik (http://peter.suschlik.de)
- Jan Dudek (http://jandudek.com)
Future plans
License
MIT License