I wrote the following Watir script as a demonstration of how to generate new methods on the fly in ruby.
See (at the time of this writing) there’s a bug in Google Phonebooks, where if you do a search that generates pages of results (e.g. “rphonebook: j smith, ny“) and then quickly click to some of the later pages, you will see:
I wanted to write a script that would randomly generate search strings – some that would yield many results, like “j smith, ca” and others that would yield few if any, like “z glinkiewicz, ak”.
I wanted the script to be able to easily run an arbitrary user-defined number of iterations…and I wanted each iteration to have it’s own assertion, so that if one failed the rest would still run. In ruby’s test::unit (which Watir gets it’s assertions from) each assertion needs it’s own method…and that led me to generating methods on the fly.
My inspirations to play with semi-random automated tests were Chris McMahon and Paul Carvalho, and I got help with my syntax through a speedy answer to my question from Brett Pettichord on wtr-general.
Here’s the script I wrote. Feel free to question me about why I did what I did or to propose improvements (I consider myself a beginning automator). In the mean time, without further ado…here’s the code:
#
# This script creates any number of randomized Google phonebook searches,
# then quickly cycles through each page of results, looking for server errors.
#
# Written to reproduce and explore a bug that I found in the Google phonebook,
# and to show a watir script of mine that's completely non-proprietary and can
# be run against publicly available software.
#
#$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..') if $0 == __FILE__
require 'test/unit'
require 'watir'
class TC_GooglePhoneBook < Test::Unit::TestCase
include Watir
$count = 15 # set number of iterations here
def setup
$ie = Watir::IE.new
$ie.bring_to_front
$ie.maximize
$ie.set_fast_speed
end
# data arrays
first_initial = ('a'..'z').to_a
last_name = ["allen","brown","glinkiewicz","johnson","jones","mason","ross",
"sanchez","smith","wieczorek","williams","woo","wolfe"]
state = ["ak","az","ca","fl","ma","mi","mt","nv","ny","wa"]
$count.times do |count|
fi = first_initial[rand(first_initial.length)]
ln = last_name[rand(last_name.length)]
st = state[rand(state.length)]
method_name = :"test_#{count}_#{fi}_#{ln}_#{st}" #dynamically create test method
define_method method_name do
search_string = fi +" "+ ln +" "+ st
$ie.goto("http://www.google.com")
$ie.form( :name, "f").text_field( :name, "q").set("rphonebook: #{search_string}")
$ie.button( :name, "btnG").click
i = 1
while $ie.link( :text, 'Next').exists? do
$ie.link( :text, 'Next').click
i = i + 1
assert_no_match( /Server Error/, $ie.text, "Page #{i} contains a server error." )
end #do
end #method
end #N.times do count
def teardown
$ie.close
end
end #TC_GooglePhoneBook