Announcing ‘responsalizr’ – test HTTP Response Codes in Ruby

Get it here:

gem install responsalizr

Responsalizr is a very small and very simple gem I’ve written that extends the standard ruby Net::HTTPResponse class with a few methods to allow for idiomatic testing of HTTP response codes. The methods added are:

  1. A numeric response code comparer:
    • code?(integer) #eg: code?(200), code?(404)
  2. Response type name comparers:
    • ok? – corresponds to code 200
    • not_found? – corresponds to code 404
    • moved_permanently? – corresponds to a 301
    • etc…

    The response type name compare methods are derived from the subclasses of Net::HTTPResponse; you can find a table with their names at the bottom of this post.

Here is an example rspec script that demonstrates what you can do with responsalizr. Each test does the same thing twice; once doing a numeric response code compare, the other doing a response type name compare:


require 'rubygems'
require 'responsalizr'

include Responsalizr

describe "Google" do
  it "should respond to the uk homepage with a 200 or an ok" do
    Response.from("http://www.google.co.uk").should be_ok
    Response.from("http://www.google.co.uk").should be_a_code 200
  end

  it "should respond with a 404 or not found" do
    Response.from("http://www.google.com/bing.aspx").should be_not_found
    Response.from("http://www.google.com/bing.aspx").should be_a_code 404
  end

  it "should respond with a 302 or a moved permanently" do
    Response.from("http://finance.google.com").should be_moved_permanently
    Response.from("http://finance.google.com").should be_a_code 301
  end

  it "should be testable through a proxy" do
    Response.from("http://www.google.co.uk", {:proxy_host => "63.223.106.54", :port => 80}).should be_ok
    Response.from("http://www.google.co.uk", {:proxy_host => "63.223.106.54", :port => 80}).should be_a_code(200)
  end
end

Chose whichever way you like (codes/names) and – I’ve only used both above for demonstration purposes.

So, if all you’re doing is testing HTTP responses for their code (whether you want to do that with codes – 404 – or names – not_found) then responsalizr is the thing for you.

About the specific response name methods and their respective codes, here’s a table that summarizes them:

Response Type Name Response Code
information? 1xx
continue? 100
switch_protocol? 101
success? 2xx
ok? 200
created? 201
accepted? 202
non_authoritative_information? 203
no_content? 204
reset_content? 205
partial_content? 206
redirection? 3xx
multiple_choice? 300
moved_permanently? 301
found? 302
see_other? 303
not_modified? 304
use_proxy? 305
temporary_redirect? 307
client_error? 4xx
bad_request? 400
unauthorized? 401
payment_required? 402
forbidden? 403
not_found? 404
method_not_allowed? 405
not_acceptable? 406
proxy_authentication_required? 407
request_time_out? 408
conflict? 409
gone? 410
length_required? 411
precondition_failed? 412
request_entity_too_large? 413
request_uri_too_long? 414
unsupported_media_type? 415
requested_range_not_satisfiable? 416
expectation_failed? 417
server_error? 5xx
internal_server_error? 500
not_implemented? 501
bad_gateway? 502
service_unavailable? 503
gateway_time_out? 504
version_not_supported? 505
unknown_response? xxx

Because of the rspec (and cucumber) predicate magic, you can use, eg, the bad_gateway?, the forbidden? and the internal_server_error? method as follows:


...should be_a_bad_gateway
...should be_forbidden
...should be_an_internal_server_error

Happy HTTP Response Code testing!

IronRuby vs. Gherkin – a temporary fix

IronRuby doesn’t currently work with the latest versions of cucumber. This is a known bug and is a real pain. There is a work around, and it’s kinda rubbish: don’t use any versions of cucumber > 0.6.3. After that version, Gherkin became a .c extension – and IronRuby doesn’t like .c extensions.

Keith Burnell (the .Net Dev Dude) has blogged about getting Cucumber working with IronRuby – you may want to take a look if you’re getting stuck.

Learning Ruby? Here’s the book for you…

Something I get asked over and over again: “Can you recommend a book that will improve my ruby skills?” There are quite a few ruby books out there, but here’s what has become my standard answer:

Learning Ruby - O'Reilly

Learning Ruby“, published by O’Reilly, is awesome. I was given my copy when an old friend and colleague moved back to Australia – he couldn’t fit the book into his suitcase! I gladly became the new owner and have since handed it out to a number of people, all of which give it rave reviews and have ended up buying their own copy.

So, if you don’t know much ruby and want to increase your knowledge of it then this is the book for you.

Announcing ‘bewildr’ – test your WPF UI apps with IronRuby

Get it here: http://www.bewildr.info

After writing an automation framework to test a WPF GUI using IronRuby and White, I decided to write a ruby-specific gem for automating WPF UI tests. Kinda like Watir, but for WPF instead of the web. The gem is called bewildr - I’ve been working on it for a while and it’s finally in a releasable state.

Here’s an example of bewildr being used in rspec to show you what it’s all about:

require 'rubygems'
require 'spec'
require 'bewildr'

describe "my example app" do
  it "should not allow invalid users to log in" do
    #start the app and wait for the main window
    @app, @main_window = Bewildr::Application.start_app_and_wait_for_window("c:\\app.exe", /App v1.\d+/)

    username_field = @main_window.get(:id => "username")
    password_field = @main_window.get(:id => "password")
    login_button   = @main_window.get(:type => :button, :name => "Go")

    #some initial checks...
    username_field.should be_enabled
    password_field.should be_a_password_field

    #attempt login with invalid user
    username_field.text = "invalidUser"
    password_field.text = "s3cr3t"
    login_button.click

    #check we're not logged in
    @main_window.get(:id => "login_message").text.should match("Wrong username/password")
  end
end

And, since bewildr was written ‘BDD-style’ there are loads of examples of its use in cucumber here: http://github.com/natritmeyer/bewildr/tree/master/features/

Cool:

  • It’s written in ruby
  • It’s free (as in speech – BSD license)
  • It’s free (as in beer – there are no bazillion-dollar yearly license fees)
  • It’s easy to install (here’s how: gem install bewildr)
  • It has a clean API (makes for idiomatic tests in cucumber/rspec)
  • It has a strong test focus (…of the testers, by the testers, for the testers…)
  • It’s been written BDD-style
  • It’s updated frequently
  • It allows tests to be written in an interpreted language (with all the flexibility which that gives you – unlike White)

Not Cool:

  • It’s limited to IronRuby, not MRI/YARV (it needs access to .Net automation)
  • It’s new – expect bugs (please raise them when you find them)
  • It’s built on top of MS UI Automation (expect quirkiness)
  • There is quite a bit to do before it does everything I want it to, eg: it doesn’t yet allow you to test for visibility, there’s no drag-and-drop; see here for more

Note: I have no intention to support anything but WPF. No WinForms, no Silverlight, no [insert non-WPF tech here]. Not yet anyway…

So, if you’re looking for a UI testing tool to automate your WPF app with, but QTP is too expensive and White is too [insert pejorative here]… Well, what are you waiting for?  http://www.bewildr.info

Testing a website on different versions of IE

So, no matter how much you argue that it’s an ancient, irrelevant browser; there’s no way you can wriggle out of having to test your web app against IE6 on WinXP. But… trying to find a machine with it lying around might be difficult. Magnanimous Microsoft have made testing your web app on different IE/Windows combinations less tedious than it could be: combine Virtual PC with a collection of pre-built images and you’re on your way. Here are the details…

First, you’ll need to install Virtual PC:

  • Download the latest version of Virtual PC from here if you’re running Windows 7
  • Download Virtual PC 2007 from here if you’re running Windows XP/Vista

Next, you’ll need to download as many of the following combinations of Windows/IE as you want from here.

The Windows/IE combinations available are:

  • IE6 / XP SP3
  • IE7 / XP SP3
  • IE7 / Vista SP1
  • IE7 / Vista SP2
  • IE7 / Vista SP3
  • IE8 / XP SP3
  • IE8 / Vista SP1
  • IE8 / Vista SP2
  • IE8 / Vista SP3

Download the images you need, start them, get your testing done before the VM runs out of time (they’re time limited) and then get back to doing something less painful!

Enjoy your multi-IE-version testing. Rather you than me ;)

Explaining Watir, Selenium and WebDriver

Something I seem to be explaining to people all the time… the relationships between Watir, Watir “2.0″, Selenium, Selenium “2.0″ and WebDriver.

Alister Scott has done an excellent job of explaining the impact of WebDriver on Selenium and Watir and what it mean for their respective futures. Read it here.

Summary:

  • Selenium 1 => dead
  • Selenium 2 == WebDriver
  • Watir 1.* (+ derivs) => dead
  • Watir 2.0 => Watir API using WebDriver to communicate with the browser

===Update===
Added version number to Watir to avoid the confusion seen here.

Testing redirects with ruby

—UPDATE—
Since writing this post, I’ve put together a gem called ‘responsalizr‘ which is a way better solution than what follows in this post. Read about it here. And now back to the original post…

Testing redirects from a web app is simple enough – make a request and check the response code making sure it’s a 301, 302 or whatever you’re expecting. The test you end up writing isn’t nice idiomatic ruby though. So, I wrote a quick monkey patch… here it is:

class Net::HTTPResponse
  #returns true if the response is a 200
  def ok?
    instance_of?(Net::HTTPOK)
  end

  #returns true if the response is a 301
  def found?
    instance_of?(Net::HTTPFound)
  end

  #returns true if the response is a 302
  def moved_permanently?
    instance_of?(Net::HTTPMovedPermanently)
  end

  #returns true for any kind of redirect (301..307)
  def redirect?
    kind_of?(Net::HTTPRedirection)
  end

  #returns the url being redirected to if this response is a redirect
  def redirect_url
    redirect? ? self['location'] : raise("Not a redirect response")
  end
end

Basically, it adds the following predicate methods to the Net::HTTPResponse class: “ok?” (returns true if response code is 200), “found?” (returns true if response code is 301), “moved_permanently?” (returns true if response code is 302) and “redirect?” (returns true if the response is a redirect – from 301..307). Because these are predicate methods, they can be used by rspec – your test code suddenly becomes much cleaner! The moneky patch also adds the “redirect_url” method which returns the url to be redirected to if the response is a redirect of some sort. The advantage of this is that your tests become much more idiomatic:


#the urls we're testing with...
@url_initially_navigated_to = "http://mail.google.com"
@expected_redirect_url = "https://www.google.com/.../etc/..."

#make the request
@response= Net::HTTP.get_response(URI.parse(@url_initially_navigated_to))

#nice idiomatic tests! - use the one you're expecting...
@response.should be_ok                #expecting a 200
@response.should be_found             #expecting a 301
@response.should be_moved_permanently #expecting a 302
@response.should be_a_redirect        #expecting anything between 301..307

#testing the url being redirected to
@response.redirect_url.should match(@expected_redirect_url)

There you go! Nice idiomatic redirect tests! Enjoy.