Bbq & sessions pool
Yesterday my friend paneq merged my patch that adds sessions pool to Bbq. This is nice addition, especially because it's mine :) I will quickly describe the ideas behind bbq and my contribution.
Bbq is a Ruby gem for acceptance testing of Web apps. The idea is to use objects - so called test actors - that have meaningful methods describing their actions and/or expectations. Similar to Cucumber, but without the natural language part (but still pretty much readable). Here's an example:
@alice = TestUser.new(:driver => :selenium)
@alice.visit_homepage
@alice.click_link "Posts"
assert @alice.see? "My post"
Bbq is rather thin wrapper around Capybara - an excellent gem that gives consistent API for different testing tools, like Selenium or rack-test.
One of use cases where Bbq really shines is testing interaction between many users. Each TestUser instance has it's own Capybara session and you can mix actions of different users:
@bob = TestUser.new
@bob.visit_homepage
@bob.click_link "Posts"
assert @bob.see? "0 comments"
@alice.fill_in "Comment", :with => "Lorem ipsum"
@alice.click_button "Add comment"
@bob.click_link "My post"
assert @bob.see? "Lorem ipsum", :within => "#comments"
Please note that @alice and @bob can use different drivers, for example one of them might be using Selenium to execute JavaScripts and the other could use rack-test (and run much faster). You can even replace TestUser with TestClient - an API client - that issues HTTP requests without a browser. This is a great approach used in some of our Facebook games that expose REST API and also a "traditional" admin panel with regular views etc. Successful testing of such app often involves combination of rack_test, Selenium and API clients (and some client-side acceptance tests, but that's a different story).
So what does my addition do? Before yesterday, each time you created a TestUser, a new Capybara session was created. This can be quite expensive, especially when using Selenium, as it means running a new browser instance. That's why we added a sessions pool, that reuses sessions between test cases. Each time you create a TestUser, it calls Bbq::Session.next. If there are "idle" sessions, one of them is returned. Otherwise it creates a new one. All existing sessions are kept in Bbq::Session.pool (i know, ugly global object) and released during test's teardown.
You can skip using session pools by providing :pool => false as TestUser option or by providing already created Capybara session with :session option.
I hope you enjoyed this post! If you're interested, try bbq today! It's really easy to get started. Bbq supports Test::Unit as well as RSpec out of the box, but you should be able to easily use it within any other test framework.
PS. Bbq was developed by folks from DRUG, a Ruby users group from Wroclaw area. If you live anywhere near, or if you want to visit Wroclaw, feel invited to one of our meetings! There's always a good amount of tech talks, flame wars and lots of beers. We're also organizing wroc_love.rb, great conference about Ruby & related topics.