README.md in bbq-0.1.0 vs README.md in bbq-0.2.0

- old
+ new

@@ -1,56 +1,30 @@ -Warning & disclaimer -==================== +# BBQ -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. +[![Build Status](https://secure.travis-ci.org/drugpl/bbq.png)](http://travis-ci.org/drugpl/bbq) [![Dependency Status](https://gemnasium.com/drugpl/bbq.png)](https://gemnasium.com/drugpl/bbq) [![Code Climate](https://codeclimate.com/github/drugpl/bbq.png)](https://codeclimate.com/github/drugpl/bbq) [![Gem Version](https://badge.fury.io/rb/bbq.png)](http://badge.fury.io/rb/bbq) -[![Build Status](https://secure.travis-ci.org/drugpl/bbq.png)](http://travis-ci.org/drugpl/bbq) [![Dependency Status](https://gemnasium.com/drugpl/bbq.png)](https://gemnasium.com/drugpl/bbq) - -BBQ -=== - Object oriented acceptance testing using personas. -* Ruby -* OOP -* DCI (Data Context Interaction) - for roles/personas -* Test framework independent, based on Capybara +* Ruby (no Gherkin) +* Objects and methods instead of steps +* Test framework independent (RSpec and Test::Unit support) +* Thins based on Capybara. +* DCI (Data Context Interaction) for roles/personas * Opinionated -Difference from Cucumber -======================== +## Setup -* No Gherkin -* Objects and methods instead of steps -* Easier code reuse -* No factories/fixtures +First, add BBQ to your apps `Gemfile`: -Example applications -==================== - -* https://github.com/pawelpacana/roundtrip - -Related examples -================ - -* https://github.com/pawelpacana/eventmachine-bbq-example -* https://github.com/drugpl/drug-site - -Installation -============ - -First, add BBQ to your apps Gemfile: - ```ruby -# Gemfile -gem "bbq", :git => "git://github.com/drugpl/bbq" +gem "bbq", "0.2.0" ``` Run install generator: ``` -rails generate bbq:install +bundle exec rails generate bbq:install ``` Require BBQ in test/test_helper.rb (in case of Test::Unit): ```ruby @@ -61,91 +35,88 @@ ```ruby require "bbq/rspec" ``` -Feature generator -================= +## Feature generator ``` -rails g bbq:test MyFeatureName +bundle exec rails g bbq:test MyFeatureName ``` -Running features -================ +## Running features For Test::Unit flavour: ``` -rake test:acceptance +bundle exec rake test:acceptance ``` For RSpec flavour: ``` -spec:acceptance +bundle exec rake spec:acceptance ``` -Examples -======== +## Examples +### Roles and Devise integration + ```ruby -module Roundtrip - class TestUser < Bbq::TestUser - include Bbq::Devise +class TestUser < Bbq::TestUser + include Bbq::Devise - def update_ticket(summary, comment) - show_ticket(summary) - fill_in "Comment", :with => comment - click_on "Add update" + 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_application - visit '/' + 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 - module TicketReporter - def open_tickets_listing - open_application - click_link 'Tickets' - end + def show_ticket(summary) + open_tickets_listing + click_on summary + end + 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 + module TicketManager + def open_administration + visit '/admin' + end - def show_ticket(summary) - open_tickets_listing - click_on summary - end + def open_tickets_listing + open_administration + click_link 'Tickets' end - module TicketManager - def open_administration - visit '/admin' - 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 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 + def show_ticket(summary) + open_tickets_listing + click_on summary end end end ``` @@ -159,21 +130,21 @@ 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 = TestUser.new alice.roles(:ticket_reporter) alice.register_and_login alice.open_ticket(summaries.first, descriptions.first) - bob = Roundtrip::TestUser.new + bob = 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 = 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) @@ -182,13 +153,72 @@ charlie.not_see!(summaries.first, descriptions.first) end end ``` -Testing REST APIs -================ +### RSpec integration +```ruby +class TestUser < Bbq::TestUser + def email + @options[:email] || "buyer@example.com" + end + + module Buyer + def ask_question(question) + fill_in "question", :with => question + fill_in "email", :with => email + click_on("Ask") + end + + def go_to_page_and_open_widget(page_url, &block) + go_to_page(page_url) + open_widget &block + end + + def go_to_page(page_url) + visit page_url + wait_until { page.find("iframe") } + end + + def open_widget + within_widget do + page.find("#widget h3").click + yield if block_given? + end + end + + ef within_widget(&block) + within_frame(widget_frame, &block) + end + + def widget_frame + page.evaluate_script("document.getElementsByTagName('iframe')[0].id") + end + end +end +``` + +```ruby +feature "ask question widget" do + let(:user) { + user = TestUser.new(:driver => :webkit) + user.roles('buyer') + user + } + + scenario "as a guest user, I should be able to ask a question" do + user.go_to_page_and_open_widget("/widget") do + user.ask_question "my question" + user.see!("Thanks!") + end + 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. ```ruby @@ -208,12 +238,11 @@ end end end ``` -Rails' URL Helpers -================ +## 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 ```ruby @@ -225,30 +254,25 @@ If you really need url helpers in your test user, just include them in your TestUser class: ```ruby require 'bbq/rails/routes' -module Roundtrip - class TestUser < Bbq::TestUser - include Bbq::Rails::Routes - end +class TestUser < Bbq::TestUser + include Bbq::Rails::Routes end ``` or just ```ruby -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 +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 ``` -Deal with Devise -================ +## Devise support ```ruby require "bbq/test_user" require "bbq/devise" @@ -265,14 +289,13 @@ user.register_and_login user.see!("Stuff after auth") end ``` -Caveats -======= +## Caveats -<h2>Timeout::Error</h2> +### 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 @@ -282,47 +305,14 @@ ```ruby # 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 -======================= +## Additional information -``` -bundle install -bundle exec rake test -``` +* [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) -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 -============ - -* Events (http://andrzejonsoftware.blogspot.com/2011/04/events-in-acceptance-tests.html) - -License -======= - -MIT License