Terse Systems

Simplest Possible Acceptance Test

| Comments

If you are fed up with walking through the same flow over and over again and want to have some code drive the browser around (what is sometimes called is known as acceptance/system/end-to-end testing) and don't know quite how: this is for you.

I remember when I first wanted to automate my tests. It was painful. Not only did I have to read through lots and lots of documentation, but so much of it was out of date, or badly written, or just incomplete. So let me say up front: I've read through a bunch of different options. The best option right now (October 2010) is Selenium Webdriver.

There are a variety of options for setting up Webdriver. If you want to do it using raw Java, then the 5 minute guide is your best option.

The way I do it normally is to use Capybara and Steak, and tie them together with rspec – I find writing tests easier this way, both because Capybara tries very hard to make the API intuitive, and because Ruby tends to be very concise. What this looks like in practice is:

# spec/acceptance/checkout_spec.rb
require File.dirname(__FILE__) + '/acceptance_helper'

# You may find the following useful:
#
# http://rspec.info/documentation/
# http://jeffkreeftmeijer.com/2010/steak-because-cucumber-is-for-vegetarians/
# http://richardconroy.blogspot.com/2010/08/capybara-reference.html
#
feature "Feature name", %q{
  In order to check out
  As a user
  I want to submit an order
} do

  scenario "Checkout" do
    email = Time.now.to_i.to_s + '@example.com'
    
    visit "/orders"
  
    within("//form[@id='commitOrderForm']") do
      fill_in "login-email", :with => email
      fill_in "login-pass", :with => 'password1'
      fill_in "login-pass-confirm", :with => 'password1'
      
      find("//input[@type='submit']").click
    end
    
    page.should have_content("Your order is complete")
  end

end

There is some stuff in the acceptance_helper.rb you have to worry about:

# spec/acceptance/acceptance_helper.rb
require File.dirname(__FILE__) + "/../spec_helper"

require "steak"
require 'capybara'
require 'capybara/dsl'

Capybara.default_driver = :selenium                # Uses webdriver by default.
Capybara.app_host = 'http://localhost:8080'        # used for relative URLs.
Capybara.run_server = false                        # turn off the internal rack server.
Capybara.default_wait_time = 5

Spec::Runner.configure do |config|
  config.include Capybara 
end

# Put your acceptance spec helpers inside /spec/acceptance/support
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}

And then there's the spec helper itself:

# spec/spec_helper.rb
require 'spec'

# Requires supporting files with custom matchers and macros, etc,
# in ./support/ and its subdirectories.
Dir[File.expand_path(File.join(File.dirname(__FILE__),'support','**','*.rb'))].each {|f| require f}

Spec::Runner.configure do |config|

end

That's pretty much it as far as Ruby code goes. Note that you will need to set up all the gems first. Here's what should be in the Gemfile:

# Gemfile
gem 'rspec'
gem 'steak'
gem 'capybara'

And, well… you'll need to install Ruby. This can be a pain, but it's at least a fairly well known one and there are many guides that will show you the way. Assuming that you're using MacOS (If you are using Linux or another Unix based system, you do not need to install MacPorts and disable the OOTB Ruby):

Disable the OOTB Ruby by moving:
  mv /usr/bin/ruby /usr/bin/ruby.bak
  mv /usr/bin/gem /usr/bin/gem.bak
Install MacPorts and add it to your PATH environment variable. (Note, this may require Xcode Tools and X11 as prerequisites, please see http://guide.macports.org/#installing)
  sudo port selfupdate
Install the MacPorts Ruby: 
 sudo port install ruby
Make sure that rubygems is up to date: 
  sudo port install rb-rubygems # or download rubygems from rubyforge -- they seem to break their update method every odd number of releases
  sudo gem update --system
Install a library that Capybara uses:
  sudo port install libffi
And then finally, we can install bundler, and then the bundle:
  sudo gem install bundler
  cd mytests # assume you have Gemfile here
  bundle install
Then to run the spec:
  spec spec/acceptance/checkout_spec.rb
And finally: I know how frustrating it can be to get everything set up even for the "simplest" solution, so I've tried my best not to leave out any steps here. If you've gone through these steps and they don't work for you, don't stew: send me an email at [email protected] Send me a stack trace and I'll see if I can help.

Comments