15 Jan 2008

Customer Testing with Ruby, Watir, RSpec and ActiveRecord

I've been using GUI based Customer Testing with Ruby and Watir as my preferred approach for the majority of my customer testing.

I really like the approach:

  • it helps us create Customer Tests that are interesting to the customer.
  • it exercises the system in exactly the same way as the end user.
  • it avoids the brittleness problems of most approaches to GUI based testing.
  • it is completely independent on the system under tests implementation technology.
  • it can be applied against any version of the system, even Production.
  • it’s tests can be run on any machine, there is no server install.

It does have some limitations:

  • it requires a developer to help the Customer write the tests.
  • it is limited to testing with Internet Explorer
These limitations are (in my view) not serious. I believe that creating customer tests is a great communication opportunity between the customer and the developer. The browser limitation is easily overcome as the FireWatir project allows us to test with the FireFox web browser.

Since the test scripts are written using a first class programming language, we can ensure our test code is Good Code. This removes much of the duplication that makes automated GUI tests so brittle.

To help me structure my tests I use RSpec. It has a nice DSL that reads more like plain English. As a bonus RSpec can automatically generate a nice looking test results report. RSpec allows us to specify the functionality of our sign up page as:


Story:
As a new user,
I can create my own password protected account
with a valid email address.

describe "The Account Signup Page" do
it "should sign up a valid user"
it "should reject a user who has already signed up"
it "should reject a user with a badly formatted email address"
it "should reject a user with no password"
it "should store the user's password in an encrypted format"
end


I use the Watir object to programmatically interact with the web browser. This allows us to “play back” our tests in the style of other automated GUI test tools. Because I want my test code to be good code, I use helper objects to clarify what is happening and to keep my tests DRY.
The addition of the Watir object to Ruby and RSpec lets me start to implement my tests:



Story:
As a new user,
I can create my own password protected account
with a valid email address.

describe "The Account Signup Page" do
it "should sign up a valid user" do
App.browser.goto App.sign_up_page.url
App.sign_up_page.do_sign_up_for sample.user.craig
App.browser.url.should be App.homepage.url
App.browser.text.contains?("Welcome to App").should be true
end
it "should reject a user who has already signed up"
it "should reject a user with a badly formatted email address"
it "should reject a user with no password"
it "should store the user's password in an encrypted format"
end


Sometimes we need to confirm data in a database, set up fixture data, or clean up the data after a test. Ruby on Rails introduced ActiveRecord library for interacting with the database. We can use Active Record in our test scripts, as ActiveRecord can be used outside of Rails. This allows us to implement our last test along the lines of:



Story:
As a new user,
I can create my own password protected account
with a valid email address.

describe "The Account Signup Page" do
it "should sign up a valid user" do
App.browser.goto App.sign_up_page.url
App.sign_up_page.do_sign_up_for sample.user.craig
App.browser.url.should be App.homepage.url
App.browser.text.contains?("Welcome to App").should be true
end
it "should reject a user who has already signed up"
it "should reject a user with a badly formatted email address"
it "should reject a user with no password"
it "should store the user's password in an encrypted format" do
App.browser.goto App.sign_up_page.url
App.sign_up_page.do_sign_up_for sample.user.craig
saved = App.data.user.find_by_email(sample.user.craig)
saved.should not be nil
saved.password.should_not eql Sample.user.craig.password
end
end



Even though these Customer Tests are implemented in Ruby they are quite small and can be read as English.