Creating Methods On the Fly…And Bugs in Google Phonebook

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:

Google Server Error

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:

6 Responses to “Creating Methods On the Fly…And Bugs in Google Phonebook”

  1. skye Says:

    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.

  2. Developer-Tester/Tester-Developer Summit Says:

    […] Jeff Fry – Generating Methods on the Fly […]

  3. subbv Says:

    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

  4. I’m a Sucker for a Testing Challenge « Test Obsessed Says:

    […] 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 […]

  5. AdhiSesha Says:

    Nice useful article keep post like this ..

  6. I’m a Sucker for a Testing Challenge Says:

    […] 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 […]

Leave a reply to I’m a Sucker for a Testing Challenge Cancel reply