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
Tags: watir
March 21, 2007 at 3:58 pm |
Your script is super readable which I totally appreciate, I was actually wandering around Google looking for WATIR tutorials and found your script, which is cool cause I didn’t really get a chance to read it at the conference. But I really like your script, especially since I’ve been trying to figure out these really cyclical and confusing scripts in that Everyday Scripting With Ruby book. You rock.
August 1, 2007 at 6:58 pm |
[…] Jeff Fry – Generating Methods on the Fly […]
May 14, 2010 at 12:37 am |
Thanks Jeff,
That really helped.
Also I have wrapped everything regarding test-methods-generation into self method:
def self.generate_on_the_fly()
# define_method stuff goes here
end
self.generate_on_the_fly() # just call the method
That helps to structure the TestCase.
Cheers
July 25, 2010 at 7:04 pm |
[…] if I could, I would use Ruby for this. Jeff Fry’s on-the-fly test method generation in Ruby technique would be a particularly good way turn the production data snapshot into a set of test cases […]
August 25, 2010 at 2:53 am |
Nice useful article keep post like this ..
August 21, 2011 at 5:30 pm |
[…] if I could, I would use Ruby for this. Jeff Fry’s on-the-fly test method generation in Ruby technique would be a particularly good way turn the production data snapshot into a set of test cases […]