In general, programming languages fall into one of two
categories: they're either compiled languages or scripting
languages. Let's explore what each of those terms means, and
understand the differences between them.
Compiled Languages: The language in which you write an
application is not actually something that your computer
understands. Your code needs to be translated into bits and
bytes that can be executed by your computer. This process of
translation is called compilation, and any language that
requires compilation is referred to as a compiled language.
Examples of compiled languages include C, C#, and Java.
For a compiled language, the actual compilation is the final
step in the development process. You invoke a compiler --
the software program that translates your final
hand-written, human-readable code into machine-readable code
-- and the compiler creates an executable file. This final
product is then able to execute independently of the
original source code.
Thus, if you make changes to your code, and you want those
changes to be incorporated into the application, you must
stop the running application, recompile it, then start the
application again.
Scripting Languages: On the other hand, a scripting language
such as Ruby, PHP, or Python, relies upon an application's
source code all of the time. Scripting languages don't have
a compiler or a compilation phase per se; instead, they use
an interpreter -- a program that runs on the web server --
to translate hand-written code into machine-executable code
on the fly. The link between the running application and
your hand-crafted code is never severed, because that
scripting code is translated every time it is invoked -- in
other words, for every web page that your application renders.
As you might have gathered from the name, the use of an
interpreter rather than a compiler is the major difference
between a scripting language and a compiled language.
The Great Performance Debate: If you've come from a
compiled-language background, you might be concerned by all
this talk of translating code on the fly -- how does it
affect the application's performance?
These concerns are valid -- translating code on the web
server every time it's needed is certainly more expensive,
performance-wise, than executing pre-compiled code, as it
requires more effort on the part of your machine's
processor. The good news is that there are ways to speed up
scripted languages, including techniques such as code
caching and persistent interpreters. However, both topics
are beyond the scope of this book.
There's also an upside to scripted languages in terms of
performance -- namely, your performance while developing an
application.
Imagine that you've just compiled a shiny new Java
application, and launched it for the first time ... and then
you notice a typo on the welcome screen. To fix it, you have
to stop your application, go back to the source code, fix
the typo, wait for the code to recompile, and restart your
application to confirm that it is fixed. And if you find
another typo, you'll need to repeat that process again.
Lather, rinse, repeat.
In a scripting language, you can fix the typo and just
reload the page in your browser -- no restart, no recompile,
no nothing. It's as simple as that.
This will help you for Automation Software Testing with Watir Tool(Ruby)
Labels
Showing posts with label Watir testing. Show all posts
Showing posts with label Watir testing. Show all posts
Friday, February 4, 2011
Tuesday, February 1, 2011
How to Create watir Frame work : Admin Module.rb
Web Application Testing in Ruby: How to Create watir Frame work : Customer Module.rb
require 'test/unit'
02 include Test::Unit::Assertions
03
04 module Admin
05 TITLE = 'ADMINISTER Pragprog Books Online Store'
06 URL = 'http://localhost:3000/admin/'
07
08 def Admin.log_on(browser, username, password)
09 browser.goto(URL)
10 if browser.link(:text,'Log out').exist? then #if already logged in
11 browser.link(:text,'Log out').click
12 end
13 browser.text_field(:id, 'user_name').set username
14 browser.text_field(:id, 'user_password').set password
15 browser.button(:value, ' LOGIN ').click
16 if browser.div(:id, 'notice').exist? then
17 return false,browser.div(:id, 'notice').text
18 else
19 return true,''
20 end
21 end
22
23 def Admin.ship_items(browser, name)
24 browser.goto(URL)
25 browser.link(:text, 'Shipping').click
26 num_orders = 0
27 index = 0
28 browser.form(:action,'/admin/ship').divs.each do |div|
29 if div.class_name == "olname"
30 index+=1
31 if div.text == name then
32 browser.form(:action,'/admin/ship').checkbox(:index, index).set
33 num_orders+=1
34 end
35 end
36 end
37
38 browser.button(:value, ' SHIP CHECKED ITEMS ').click
39
40 if num_orders == 1 then
41 assert_equal(browser.div(:id,"notice").text, "One order marked as shipped","Correct notice")
42 elsif num_orders > 1 then
43 assert_equal(browser.div(:id,"notice").text, "#{num_orders} orders marked as shipped","Correct notice")
44 end
45 return true, num_orders.to_s
46 end
47
48 end
require 'test/unit'
02 include Test::Unit::Assertions
03
04 module Admin
05 TITLE = 'ADMINISTER Pragprog Books Online Store'
06 URL = 'http://localhost:3000/admin/'
07
08 def Admin.log_on(browser, username, password)
09 browser.goto(URL)
10 if browser.link(:text,'Log out').exist? then #if already logged in
11 browser.link(:text,'Log out').click
12 end
13 browser.text_field(:id, 'user_name').set username
14 browser.text_field(:id, 'user_password').set password
15 browser.button(:value, ' LOGIN ').click
16 if browser.div(:id, 'notice').exist? then
17 return false,browser.div(:id, 'notice').text
18 else
19 return true,''
20 end
21 end
22
23 def Admin.ship_items(browser, name)
24 browser.goto(URL)
25 browser.link(:text, 'Shipping').click
26 num_orders = 0
27 index = 0
28 browser.form(:action,'/admin/ship').divs.each do |div|
29 if div.class_name == "olname"
30 index+=1
31 if div.text == name then
32 browser.form(:action,'/admin/ship').checkbox(:index, index).set
33 num_orders+=1
34 end
35 end
36 end
37
38 browser.button(:value, ' SHIP CHECKED ITEMS ').click
39
40 if num_orders == 1 then
41 assert_equal(browser.div(:id,"notice").text, "One order marked as shipped","Correct notice")
42 elsif num_orders > 1 then
43 assert_equal(browser.div(:id,"notice").text, "#{num_orders} orders marked as shipped","Correct notice")
44 end
45 return true, num_orders.to_s
46 end
47
48 end
Labels:
General Testing,
Watir Framework,
Watir testing
How to Create watir Frame work : Customer Module.rb
Web Application Testing in Ruby: How to Create watir Frame work : Test Driver tc_main.rb
require 'test/unit'
002 include Test::Unit::Assertions
003
004 module Customer
005
006 TITLE = 'Pragprog Books Online Store'
007 URL = 'http://localhost:3000/store/'
008
009 # Description:: Adds a book named 'book_title' to cart
010 def Customer.add_book(browser, book_title)
011 browser.goto(URL)
012 # Check if title is already in cart - so we can check it was added correctly
013 browser.link(:text,'Show my cart').click
014 prev_cart_count = 0
015 prev_cart_total = 0.00
016 if not browser.div(:text,'Your cart is currently empty').exist? then
017 # We have a non-empty cart
018 for row in browser.table(:index,1)
019 if row[2].text == book_title then
020 prev_cart_count = row[1].text.to_i
021 break
022 end
023 end
024 prev_cart_total = browser.cell(:id, 'totalcell').text[1..-1].to_f #remove $ sign
025 browser.link(:text, 'Continue shopping').click
026 end
027
028 found = false
029 book_price = 0.00
030 1.upto(browser.divs.length) do |index|
031 if (browser.div(:index,index).attribute_value('className') == 'catalogentry') and (browser.div(:index,index).h3(:text,book_title).exists?) then
032 book_price = browser.div(:index,index).span(:class, 'catalogprice').text[1..-1].to_f #remove $ sign
033 browser.div(:index,index).link(:class,'addtocart').click
034 found = true
035 break
036 end
037 end
038 if not found then
039 return false,'Could not locate title in store'
040 end
041
042 new_cart_count = 0
043 for row in browser.table(:index,1)
044 if row[2].text == book_title then
045 new_cart_count = row[1].text.to_i
046 break
047 end
048 end
049 new_cart_total = browser.cell(:id, 'totalcell').text[1..-1].to_f # remove $ sign
050 assert_equal(new_cart_count,(prev_cart_count+1), "Ensure that new quantity is now one greater than previously")
051 assert_equal(new_cart_total,(prev_cart_total + book_price), "Ensure that new cart total is old cart total plus book price")
052 browser.link(:text, 'Continue shopping').click
053 return true,new_cart_total
054 end
055
056 def Customer.check_out(browser, customerName, customerEmail, customerAddress, customerPaymentMethod)
057 browser.goto(URL)
058 browser.link(:text,'Show my cart').click
059 if browser.div(:text,'Your cart is currently empty').exist? then
060 return false,'Your cart is currently empty'
061 end
062 browser.link(:text,"Checkout").click
063 browser.text_field(:id, 'order_name').set(customerName)
064 browser.text_field(:id, 'order_email').set(customerEmail)
065 browser.text_field(:id, 'order_address').set(customerAddress)
066 begin
067 browser.select_list(:id, 'order_pay_type').select(customerPaymentMethod)
068 rescue Watir::Exception::NoValueFoundException
069 flunk('Could not locate customer payment method in drop down list: '+customerPaymentMethod)
070 end
071 browser.button(:name, 'commit').click
072 if browser.div(:id,'errorExplanation').exist? then
073 error = ''
074 1.upto(browser.div(:id,'errorExplanation').lis.length) do |index|
075 error << (browser.div(:id,'errorExplanation').li(:index,index).text + ",")
076 end
077 browser.link(:text,'Continue shopping').click
078 return false, error
079 end
080 assert_equal(browser.div(:id,'notice').text, 'Thank you for your order.',"Thank you for your order should appear.")
081 return true,''
082 end
083
084 def Customer.empty_cart(browser)
085 browser.goto(URL)
086 browser.link(:text,"Show my cart").click
087 if browser.div(:text,"Your cart is currently empty").exist? then
088 assert('Cart was never empty')
089 else
090 browser.link(:text,'Empty cart').click
091 assert_equal(browser.div(:id, 'notice').text,'Your cart is now empty')
092 end
093 return true,''
094 end
095
096 def Customer.check_cart_total(browser, exp_total)
097 browser.goto(URL)
098 browser.link(:text,'Show my cart').click
099 if browser.div(:text,'Your cart is currently empty').exist? then
100 return false,'Your cart is currently empty'
101 end
102 act_total = browser.cell(:id, 'totalcell').text[1..-1].to_f
103 assert_equal(act_total,exp_total.to_f,"Check that cart total is as expected.")
104 return true,act_total
105 end
106 end
require 'test/unit'
002 include Test::Unit::Assertions
003
004 module Customer
005
006 TITLE = 'Pragprog Books Online Store'
007 URL = 'http://localhost:3000/store/'
008
009 # Description:: Adds a book named 'book_title' to cart
010 def Customer.add_book(browser, book_title)
011 browser.goto(URL)
012 # Check if title is already in cart - so we can check it was added correctly
013 browser.link(:text,'Show my cart').click
014 prev_cart_count = 0
015 prev_cart_total = 0.00
016 if not browser.div(:text,'Your cart is currently empty').exist? then
017 # We have a non-empty cart
018 for row in browser.table(:index,1)
019 if row[2].text == book_title then
020 prev_cart_count = row[1].text.to_i
021 break
022 end
023 end
024 prev_cart_total = browser.cell(:id, 'totalcell').text[1..-1].to_f #remove $ sign
025 browser.link(:text, 'Continue shopping').click
026 end
027
028 found = false
029 book_price = 0.00
030 1.upto(browser.divs.length) do |index|
031 if (browser.div(:index,index).attribute_value('className') == 'catalogentry') and (browser.div(:index,index).h3(:text,book_title).exists?) then
032 book_price = browser.div(:index,index).span(:class, 'catalogprice').text[1..-1].to_f #remove $ sign
033 browser.div(:index,index).link(:class,'addtocart').click
034 found = true
035 break
036 end
037 end
038 if not found then
039 return false,'Could not locate title in store'
040 end
041
042 new_cart_count = 0
043 for row in browser.table(:index,1)
044 if row[2].text == book_title then
045 new_cart_count = row[1].text.to_i
046 break
047 end
048 end
049 new_cart_total = browser.cell(:id, 'totalcell').text[1..-1].to_f # remove $ sign
050 assert_equal(new_cart_count,(prev_cart_count+1), "Ensure that new quantity is now one greater than previously")
051 assert_equal(new_cart_total,(prev_cart_total + book_price), "Ensure that new cart total is old cart total plus book price")
052 browser.link(:text, 'Continue shopping').click
053 return true,new_cart_total
054 end
055
056 def Customer.check_out(browser, customerName, customerEmail, customerAddress, customerPaymentMethod)
057 browser.goto(URL)
058 browser.link(:text,'Show my cart').click
059 if browser.div(:text,'Your cart is currently empty').exist? then
060 return false,'Your cart is currently empty'
061 end
062 browser.link(:text,"Checkout").click
063 browser.text_field(:id, 'order_name').set(customerName)
064 browser.text_field(:id, 'order_email').set(customerEmail)
065 browser.text_field(:id, 'order_address').set(customerAddress)
066 begin
067 browser.select_list(:id, 'order_pay_type').select(customerPaymentMethod)
068 rescue Watir::Exception::NoValueFoundException
069 flunk('Could not locate customer payment method in drop down list: '+customerPaymentMethod)
070 end
071 browser.button(:name, 'commit').click
072 if browser.div(:id,'errorExplanation').exist? then
073 error = ''
074 1.upto(browser.div(:id,'errorExplanation').lis.length) do |index|
075 error << (browser.div(:id,'errorExplanation').li(:index,index).text + ",")
076 end
077 browser.link(:text,'Continue shopping').click
078 return false, error
079 end
080 assert_equal(browser.div(:id,'notice').text, 'Thank you for your order.',"Thank you for your order should appear.")
081 return true,''
082 end
083
084 def Customer.empty_cart(browser)
085 browser.goto(URL)
086 browser.link(:text,"Show my cart").click
087 if browser.div(:text,"Your cart is currently empty").exist? then
088 assert('Cart was never empty')
089 else
090 browser.link(:text,'Empty cart').click
091 assert_equal(browser.div(:id, 'notice').text,'Your cart is now empty')
092 end
093 return true,''
094 end
095
096 def Customer.check_cart_total(browser, exp_total)
097 browser.goto(URL)
098 browser.link(:text,'Show my cart').click
099 if browser.div(:text,'Your cart is currently empty').exist? then
100 return false,'Your cart is currently empty'
101 end
102 act_total = browser.cell(:id, 'totalcell').text[1..-1].to_f
103 assert_equal(act_total,exp_total.to_f,"Check that cart total is as expected.")
104 return true,act_total
105 end
106 end
Labels:
General Testing,
Watir Framework,
Watir testing
How to Create watir Frame work : Test Driver tc_main.rb
Web Application Testing in Ruby: How to Create watir Frame work ?
$:.unshift File.join(File.dirname(__FILE__), ".", "lib")
002 require 'watir'
003 require 'roo'
004 require 'test/unit'
005 require 'customer'
006 require 'admin'
007 $stdout = File.new('log.txt',File::WRONLY|File::APPEND|File::CREAT)
008 $stderr = File.new('log.txt',File::WRONLY|File::APPEND|File::CREAT)
009
010 class TC_WatirMelon < Test::Unit::TestCase
011 @@colmap = {:module_name=>0, :method_name=>1, :comments=>2, :exp_outcome=>3, :exp_error=>4, :first_param=>5}
012 @@ss_format = ARGV[0]
013 @@specified_browser = ARGV[1]
014
015 def setup
016 puts "[Starting at #{Time.now}]\n"
017 case @@ss_format
018 when "excel"
019 @ss = Excel.new("watirmelon.xls")
020 when "wiki"
021 @ss = Excel.new("http://localhost:8080/download/attachments/2097153/watirmelon.xls")
022 when "gdocs"
023 @ss = Google.new("0AtL3mPY2rEqmdEY3XzRqUlZKSmM5Z3EtM21UdFdqb1E")
024 else
025 @ss = Openoffice.new("watirmelon.ods")
026 end
027 @ss.default_sheet = @ss.sheets.first
028 case @@specified_browser
029 when "firefox"
030 Watir::Browser.default = 'firefox'
031 @browser = Watir::Browser.new
032 else
033 Watir::Browser.default = 'ie'
034 @browser = Watir::Browser.new
035 @browser.speed = :zippy
036 @browser.visible = true
037 end
038 end
039
040 def test_run_sheet()
041 @ss.first_row.upto(@ss.last_row) do |row|
042 #Read row into array
043 line = Array.new
044 @ss.first_column.upto(@ss.last_column) do |column|
045 line << @ss.cell(row, column).to_s.strip
046 end
047
048 module_name = line[@@colmap[:module_name]]
049 if module_name != "Function" then #if not a header
050 method_name = line[@@colmap[:method_name]].downcase.gsub(' ','_') #automatically determine ruby method name based upon data sheet
051 exp_outcome = line[@@colmap[:exp_outcome]]
052 exp_error = line[@@colmap[:exp_error]]
053 first_param = @@colmap[:first_param]
054 required_module = Kernel.const_get(module_name)
055 required_method = required_module.method(method_name)
056 arity = required_method.arity() # this is how many arguments the method requires, it is negative if a 'catch all' is supplied.
057 arity = ((arity * -1) - 1) if arity < 0 # arity is negative when there is a 'catch all'
058 arity = arity-1 # Ignore the first browser parameter
059 unless arity == 0
060 parameters = line[first_param..first_param+(arity-1)]
061 else
062 parameters = []
063 end
064 begin
065 act_outcome, act_output = required_method.call(@browser, *parameters)
066 rescue Test::Unit::AssertionFailedError => e
067 self.send(:add_failure, e.message, e.backtrace)
068 act_outcome = false
069 act_output = e.message
070 end
071 if (exp_outcome == 'Success') and act_outcome then
072 assert(true, "Expected outcome and actual outcome are the same")
073 result = 'PASS'
074 elsif (exp_outcome == 'Error') and (not act_outcome) and (exp_error.strip! == act_output.strip!)
075 assert(true, "Expected outcome and actual outcome are the same, and error messages match")
076 result = 'PASS'
077 else
078 result = 'FAIL'
079 begin
080 assert(false,"Row: #{row}: Expected outcome and actual outcome for #{method_name} for #{module_name} do not match, or error messages do not match.")
081 rescue Test::Unit::AssertionFailedError => e
082 self.send(:add_failure, e.message, e.backtrace)
083 end
084 end
085 puts "###########################################"
086 puts "[Running: #{module_name}.#{method_name}]"
087 puts "[Expected Outcome: #{exp_outcome}]"
088 puts "[Expected Error: #{exp_error}]"
089 puts "[Actual Outcome: Success]" if act_outcome
090 puts "[Actual Outcome: Error]" if not act_outcome
091 puts "[Actual Output: #{act_output}]"
092 puts "[RESULT: #{result}]"
093 puts "###########################################"
094 end
095 end
096 end
097
098 def teardown
099 @browser.close
100 puts "[Finishing at #{Time.now}]\n\n"
101 end
102
103 end
$:.unshift File.join(File.dirname(__FILE__), ".", "lib")
002 require 'watir'
003 require 'roo'
004 require 'test/unit'
005 require 'customer'
006 require 'admin'
007 $stdout = File.new('log.txt',File::WRONLY|File::APPEND|File::CREAT)
008 $stderr = File.new('log.txt',File::WRONLY|File::APPEND|File::CREAT)
009
010 class TC_WatirMelon < Test::Unit::TestCase
011 @@colmap = {:module_name=>0, :method_name=>1, :comments=>2, :exp_outcome=>3, :exp_error=>4, :first_param=>5}
012 @@ss_format = ARGV[0]
013 @@specified_browser = ARGV[1]
014
015 def setup
016 puts "[Starting at #{Time.now}]\n"
017 case @@ss_format
018 when "excel"
019 @ss = Excel.new("watirmelon.xls")
020 when "wiki"
021 @ss = Excel.new("http://localhost:8080/download/attachments/2097153/watirmelon.xls")
022 when "gdocs"
023 @ss = Google.new("0AtL3mPY2rEqmdEY3XzRqUlZKSmM5Z3EtM21UdFdqb1E")
024 else
025 @ss = Openoffice.new("watirmelon.ods")
026 end
027 @ss.default_sheet = @ss.sheets.first
028 case @@specified_browser
029 when "firefox"
030 Watir::Browser.default = 'firefox'
031 @browser = Watir::Browser.new
032 else
033 Watir::Browser.default = 'ie'
034 @browser = Watir::Browser.new
035 @browser.speed = :zippy
036 @browser.visible = true
037 end
038 end
039
040 def test_run_sheet()
041 @ss.first_row.upto(@ss.last_row) do |row|
042 #Read row into array
043 line = Array.new
044 @ss.first_column.upto(@ss.last_column) do |column|
045 line << @ss.cell(row, column).to_s.strip
046 end
047
048 module_name = line[@@colmap[:module_name]]
049 if module_name != "Function" then #if not a header
050 method_name = line[@@colmap[:method_name]].downcase.gsub(' ','_') #automatically determine ruby method name based upon data sheet
051 exp_outcome = line[@@colmap[:exp_outcome]]
052 exp_error = line[@@colmap[:exp_error]]
053 first_param = @@colmap[:first_param]
054 required_module = Kernel.const_get(module_name)
055 required_method = required_module.method(method_name)
056 arity = required_method.arity() # this is how many arguments the method requires, it is negative if a 'catch all' is supplied.
057 arity = ((arity * -1) - 1) if arity < 0 # arity is negative when there is a 'catch all'
058 arity = arity-1 # Ignore the first browser parameter
059 unless arity == 0
060 parameters = line[first_param..first_param+(arity-1)]
061 else
062 parameters = []
063 end
064 begin
065 act_outcome, act_output = required_method.call(@browser, *parameters)
066 rescue Test::Unit::AssertionFailedError => e
067 self.send(:add_failure, e.message, e.backtrace)
068 act_outcome = false
069 act_output = e.message
070 end
071 if (exp_outcome == 'Success') and act_outcome then
072 assert(true, "Expected outcome and actual outcome are the same")
073 result = 'PASS'
074 elsif (exp_outcome == 'Error') and (not act_outcome) and (exp_error.strip! == act_output.strip!)
075 assert(true, "Expected outcome and actual outcome are the same, and error messages match")
076 result = 'PASS'
077 else
078 result = 'FAIL'
079 begin
080 assert(false,"Row: #{row}: Expected outcome and actual outcome for #{method_name} for #{module_name} do not match, or error messages do not match.")
081 rescue Test::Unit::AssertionFailedError => e
082 self.send(:add_failure, e.message, e.backtrace)
083 end
084 end
085 puts "###########################################"
086 puts "[Running: #{module_name}.#{method_name}]"
087 puts "[Expected Outcome: #{exp_outcome}]"
088 puts "[Expected Error: #{exp_error}]"
089 puts "[Actual Outcome: Success]" if act_outcome
090 puts "[Actual Outcome: Error]" if not act_outcome
091 puts "[Actual Output: #{act_output}]"
092 puts "[RESULT: #{result}]"
093 puts "###########################################"
094 end
095 end
096 end
097
098 def teardown
099 @browser.close
100 puts "[Finishing at #{Time.now}]\n\n"
101 end
102
103 end
Labels:
General Testing,
Watir Framework,
Watir testing
How to Create watir Frame work ?
One common challenge I see over and over again is people figuring out how to design a logical and maintainable automated testing framework. I have designed quite a few frameworks for various projects, but one thing that has consistently been a win for me is purposely separating test case and test execution design.
It’s therefore logical that the design of my Watir framework deliberately separates test case design and test execution design so that:
■test case design is done visually in spreadsheets; and
■test execution design is done in ruby methods, because code is the most efficient and maintainable way.
Since I last published details about my framework on this blog, I have started doing assertions using the Test::Unit ruby library. The reasons I chose Test::Unit are:
■it is easy to ‘mix-in’ Test::Unit assertions into modules of ruby code using include Test::Unit::Assertions;
■it is included with ruby;
■ruby scripts with Test::Unit::TestCase are instantly executable, in my case, from SciTE;
■its assertions are easy to understand and use.
I have also made some other improvements to my framework code, including:
■the ability to specify browser types, and spreadsheet sources, as command line arguments (with defaults);
■logging test output to a file;
■no longer attaching to an open browser, the same browser instance is used completely for all tests (and elegantly closed at the end).
The main design has been kept the same, in that a spreadsheet (either excel, openoffice or Google Docs) contains tests grouped by functional area, which call a method in a particular module.
The great thing about my framework is that adding a new test is a matter of designing the test case, and then writing the ruby method: as the methods are called dynamically from the spreadsheet, no extra glue is needed!
Enough talk, here’s the code. The Google spreadsheet is here. You can find a .zip file of all the required files to run it here. It runs on the depot app, which you get here. You will need two gems: Watir (oh duh), and Roo.
It’s therefore logical that the design of my Watir framework deliberately separates test case design and test execution design so that:
■test case design is done visually in spreadsheets; and
■test execution design is done in ruby methods, because code is the most efficient and maintainable way.
Since I last published details about my framework on this blog, I have started doing assertions using the Test::Unit ruby library. The reasons I chose Test::Unit are:
■it is easy to ‘mix-in’ Test::Unit assertions into modules of ruby code using include Test::Unit::Assertions;
■it is included with ruby;
■ruby scripts with Test::Unit::TestCase are instantly executable, in my case, from SciTE;
■its assertions are easy to understand and use.
I have also made some other improvements to my framework code, including:
■the ability to specify browser types, and spreadsheet sources, as command line arguments (with defaults);
■logging test output to a file;
■no longer attaching to an open browser, the same browser instance is used completely for all tests (and elegantly closed at the end).
The main design has been kept the same, in that a spreadsheet (either excel, openoffice or Google Docs) contains tests grouped by functional area, which call a method in a particular module.
The great thing about my framework is that adding a new test is a matter of designing the test case, and then writing the ruby method: as the methods are called dynamically from the spreadsheet, no extra glue is needed!
Enough talk, here’s the code. The Google spreadsheet is here. You can find a .zip file of all the required files to run it here. It runs on the depot app, which you get here. You will need two gems: Watir (oh duh), and Roo.
Labels:
General Testing,
Watir Framework,
Watir testing
Friday, January 28, 2011
How to deal with Java scripts and frame?
I came across this difficulty when I was trying to automate a webpage that was primarily built in Javascript; this webpage also always had the same href (or web address) and also was built with many frames. The problem that I ran into was that I could find the links with the IE developer toolbar to get their ids, but whenever I tried to access them, I could not, I was given an error message saying that they did not exist. At this point in time I thought the issue I had was with javascript, but I was incorrect!
A lot of hunting on the interwebs led me, ironically, back to the watir main documentation, where I discovered that my issue was really with frames! When a website has frames, you need to specify what frame the link is in to actually access it, for example:
ie.frame(“main”).link(:id,”UW_CO_JOBTITLE_HL$”).click
Or in general terms:
ie.frame(“FRAMENAME”).link(:id, “LINKID”).click
And there we have, you can now access links that are in frames, hopefully this saves someone all of the hunting that I had to do! This is also a really good example of how difficult it is to find a solution to something when you are not sure what the problem was; I thought the problem was with JavaScript, so I was searching for that, but it was in fact as stated above with the frames!
A lot of hunting on the interwebs led me, ironically, back to the watir main documentation, where I discovered that my issue was really with frames! When a website has frames, you need to specify what frame the link is in to actually access it, for example:
ie.frame(“main”).link(:id,”UW_CO_JOBTITLE_HL$”).click
Or in general terms:
ie.frame(“FRAMENAME”).link(:id, “LINKID”).click
And there we have, you can now access links that are in frames, hopefully this saves someone all of the hunting that I had to do! This is also a really good example of how difficult it is to find a solution to something when you are not sure what the problem was; I thought the problem was with JavaScript, so I was searching for that, but it was in fact as stated above with the frames!
IE Automation testing with Ruby: How to catch popup windows?
Firstly I need to define what I mean my pop-up Windows. The pop-up windows that cause trouble are not internet explorer based windows, they are actually ‘Windows’ windows, (sorry if thats confusing). The ones that I am referring to are the ones that come up when, for example, you click on a download link. These are inherently a pain because of the fact that they are not IE windows. Luckily there is a pretty simple work around that i have come up with.
Ruby has access to the WIN32OLE library , which is basically like an API for windows applications. What you can do is use this library to catch these pop up windows. Below is the code that you’ll need to run in a Ruby script:
require ‘win32ole’ #Loads the win32ole library
wsh = WIN32OLE.new(Wscript.Shell) #For more info click here
wsh.AppActivate(‘Connect’) #Focuses on a given application based on its Title
At this point you can manipulate the window, for example, with a SendKeys command:
wsh.SendKeys(“%{F4}”) #This would close the program with Alt-F4
This clearly has it’s limitations because during this time you cannot be doing things on your computer, because the AppActivate would fail. I am still looking for a lower level at which I can address this problem.
Now everyone likes to see code at work, so I have written a quick script that goes to the Notepad++ downloads page, clicks the download link, and then closes the pop-up download window. As a quick side note, if you do not already use notepad++ I highly recommend it!
require ‘win32ole’
require ‘watir’
wsh = WIN32OLE.new(‘Wscript.Shell’)
ie= Watir::IE.new
ie.goto(“http://notepad-plus.sourceforge.net/uk/site.htm”)
ie.frame(:name, “index”).link(:text, “Download”).click #Good example of how to execute a link in a Frame
ie.frame(:name, “index”).link(:text, “Download Notepad++ executable files”).click
sleep 20 #need to wait for source forge to load it is slow
ie1 = Watir::IE.attach(:title, /Source/)
ie1.link(:id, “showfiles_download_file_pkg0_1rel0_2″).click
wsh.AppActivate(“File Download – Security Warning”) #Focuses on the pop up window
wsh.SendKeys(“%{F4}”) #Sends the alt-F4 command to the window to close it
Watir::IE.close_all #Closes all open IE windows
Ruby has access to the WIN32OLE library , which is basically like an API for windows applications. What you can do is use this library to catch these pop up windows. Below is the code that you’ll need to run in a Ruby script:
require ‘win32ole’ #Loads the win32ole library
wsh = WIN32OLE.new(Wscript.Shell) #For more info click here
wsh.AppActivate(‘Connect’) #Focuses on a given application based on its Title
At this point you can manipulate the window, for example, with a SendKeys command:
wsh.SendKeys(“%{F4}”) #This would close the program with Alt-F4
This clearly has it’s limitations because during this time you cannot be doing things on your computer, because the AppActivate would fail. I am still looking for a lower level at which I can address this problem.
Now everyone likes to see code at work, so I have written a quick script that goes to the Notepad++ downloads page, clicks the download link, and then closes the pop-up download window. As a quick side note, if you do not already use notepad++ I highly recommend it!
require ‘win32ole’
require ‘watir’
wsh = WIN32OLE.new(‘Wscript.Shell’)
ie= Watir::IE.new
ie.goto(“http://notepad-plus.sourceforge.net/uk/site.htm”)
ie.frame(:name, “index”).link(:text, “Download”).click #Good example of how to execute a link in a Frame
ie.frame(:name, “index”).link(:text, “Download Notepad++ executable files”).click
sleep 20 #need to wait for source forge to load it is slow
ie1 = Watir::IE.attach(:title, /Source/)
ie1.link(:id, “showfiles_download_file_pkg0_1rel0_2″).click
wsh.AppActivate(“File Download – Security Warning”) #Focuses on the pop up window
wsh.SendKeys(“%{F4}”) #Sends the alt-F4 command to the window to close it
Watir::IE.close_all #Closes all open IE windows
How to catch Popup windows?
The pop-up windows that cause trouble are not internet explorer based windows, they are actually ‘Windows’ windows, (sorry if thats confusing). The ones that I am referring to are the ones that come up when, for example, you click on a download link. These are inherently a pain because of the fact that they are not IE windows. Luckily there is a pretty simple work around that i have come up with.
Ruby has access to the WIN32OLE library , which is basically like an API for windows applications. What you can do is use this library to catch these pop up windows. Below is the code that you’ll need to run in a Ruby script:
require ‘win32ole’ #Loads the win32ole library
wsh = WIN32OLE.new(Wscript.Shell) #For more info click here
wsh.AppActivate(‘Connect’) #Focuses on a given application based on its Title
At this point you can manipulate the window, for example, with a SendKeys command:
wsh.SendKeys(“%{F4}”) #This would close the program with Alt-F4
This clearly has it’s limitations because during this time you cannot be doing things on your computer, because the AppActivate would fail. I am still looking for a lower level at which I can address this problem.
Now everyone likes to see code at work, so I have written a quick script that goes to the Notepad++ downloads page, clicks the download link, and then closes the pop-up download window. As a quick side note, if you do not already use notepad++ I highly recommend it!
require ‘win32ole’
require ‘watir’
wsh = WIN32OLE.new(‘Wscript.Shell’)
ie= Watir::IE.new
ie.goto(“http://notepad-plus.sourceforge.net/uk/site.htm”)
ie.frame(:name, “index”).link(:text, “Download”).click #Good example of how to execute a link in a Frame
ie.frame(:name, “index”).link(:text, “Download Notepad++ executable files”).click
sleep 20 #need to wait for source forge to load it is slow
ie1 = Watir::IE.attach(:title, /Source/)
ie1.link(:id, “showfiles_download_file_pkg0_1rel0_2″).click
wsh.AppActivate(“File Download – Security Warning”) #Focuses on the pop up window
wsh.SendKeys(“%{F4}”) #Sends the alt-F4 command to the window to close it
Watir::IE.close_all #Closes all open IE windows
Ruby has access to the WIN32OLE library , which is basically like an API for windows applications. What you can do is use this library to catch these pop up windows. Below is the code that you’ll need to run in a Ruby script:
require ‘win32ole’ #Loads the win32ole library
wsh = WIN32OLE.new(Wscript.Shell) #For more info click here
wsh.AppActivate(‘Connect’) #Focuses on a given application based on its Title
At this point you can manipulate the window, for example, with a SendKeys command:
wsh.SendKeys(“%{F4}”) #This would close the program with Alt-F4
This clearly has it’s limitations because during this time you cannot be doing things on your computer, because the AppActivate would fail. I am still looking for a lower level at which I can address this problem.
Now everyone likes to see code at work, so I have written a quick script that goes to the Notepad++ downloads page, clicks the download link, and then closes the pop-up download window. As a quick side note, if you do not already use notepad++ I highly recommend it!
require ‘win32ole’
require ‘watir’
wsh = WIN32OLE.new(‘Wscript.Shell’)
ie= Watir::IE.new
ie.goto(“http://notepad-plus.sourceforge.net/uk/site.htm”)
ie.frame(:name, “index”).link(:text, “Download”).click #Good example of how to execute a link in a Frame
ie.frame(:name, “index”).link(:text, “Download Notepad++ executable files”).click
sleep 20 #need to wait for source forge to load it is slow
ie1 = Watir::IE.attach(:title, /Source/)
ie1.link(:id, “showfiles_download_file_pkg0_1rel0_2″).click
wsh.AppActivate(“File Download – Security Warning”) #Focuses on the pop up window
wsh.SendKeys(“%{F4}”) #Sends the alt-F4 command to the window to close it
Watir::IE.close_all #Closes all open IE windows
How to handle JavaScripts popups?
These JavaScript popups cause trouble as they interrupt the page from fully loading, causing Watir to wait (as the page is waiting), which means the next command in your script will never be reached. Previous work arounds to this were to use watirs built in click_no_wait, but I have that to be extremely temperamental and did not always work depending on which element the click was being performed on.
The new and improved method is to have a completely separate process that runs in the background and is continually checking for JavaScript pop ups. AutoIt commands are used to first locate the pop-up and then depending on what text or title is present in the pop up and different action can be performed on it. Unfortunately the same code cannot be used for both IE and FF due to the fact that the AutoIt controls cannot perform the same actions on IE pop-ups as it can on FF pop-ups. I have included the code for both below:
clickPopupsIE.rb
require 'win32ole'
begin
autoit WIN32OLE.new('AutoItX3.Control')
loop do
autoit.ControlClick("Windows Internet Explorer",'', 'OK')
autoit.ControlClick("Security Information",'', '&Yes')
autoit.ControlClick("Security Alert",'', '&Yes')
autoit.ControlClick("Security Warning",'', 'Yes')
autoit.ControlClick("Message from webpage",'', 'OK')
sleep 1
end
rescue Exception > e
puts e
end
clickPopupsFF.rb
require 'win32ole'
websiteName = "w3schools.com"
begin
autoit = WIN32OLE.new('AutoItX3.Control')
loop do
autoit.winActivate("The page at http://#{websiteName} says:")
autoit.Send("{ENTER}") if(autoit.WinWait("The page at http://#{websiteName} says:",'',2) == 1)
end
rescue Exception => e
puts e
end
These two scripts can then be called from any of your other Watir scripts using the following two functions scripts:
require 'win32/process'
def callPopupKillerFF
$pid = Process.create(:app_name => 'ruby clickPopupsFF.rb', :creation_flags => Process::DETACHED_PROCESS).process_id
end
def callPopupKillerIE
$pid = Process.create(:app_name => 'ruby clickPopupsIE.rb', :creation_flags => Process::DETACHED_PROCESS).process_id
end
def killPopupKiller
Process.kill(9,$pid)
end
As you can see above you do need to require one more ruby gem, ‘win32/process’, this is used to run the popup clicker as a separate process that runs in the background. Once you have those functions in place you can simply call:
callPopupKillerIE #Starts the IE popup killer
#Some watir code that results in a popup#
killPopupKiller #Kills the popup killer process, so that you do not end up with 5 of them running!
The new and improved method is to have a completely separate process that runs in the background and is continually checking for JavaScript pop ups. AutoIt commands are used to first locate the pop-up and then depending on what text or title is present in the pop up and different action can be performed on it. Unfortunately the same code cannot be used for both IE and FF due to the fact that the AutoIt controls cannot perform the same actions on IE pop-ups as it can on FF pop-ups. I have included the code for both below:
clickPopupsIE.rb
require 'win32ole'
begin
autoit WIN32OLE.new('AutoItX3.Control')
loop do
autoit.ControlClick("Windows Internet Explorer",'', 'OK')
autoit.ControlClick("Security Information",'', '&Yes')
autoit.ControlClick("Security Alert",'', '&Yes')
autoit.ControlClick("Security Warning",'', 'Yes')
autoit.ControlClick("Message from webpage",'', 'OK')
sleep 1
end
rescue Exception > e
puts e
end
clickPopupsFF.rb
require 'win32ole'
websiteName = "w3schools.com"
begin
autoit = WIN32OLE.new('AutoItX3.Control')
loop do
autoit.winActivate("The page at http://#{websiteName} says:")
autoit.Send("{ENTER}") if(autoit.WinWait("The page at http://#{websiteName} says:",'',2) == 1)
end
rescue Exception => e
puts e
end
These two scripts can then be called from any of your other Watir scripts using the following two functions scripts:
require 'win32/process'
def callPopupKillerFF
$pid = Process.create(:app_name => 'ruby clickPopupsFF.rb', :creation_flags => Process::DETACHED_PROCESS).process_id
end
def callPopupKillerIE
$pid = Process.create(:app_name => 'ruby clickPopupsIE.rb', :creation_flags => Process::DETACHED_PROCESS).process_id
end
def killPopupKiller
Process.kill(9,$pid)
end
As you can see above you do need to require one more ruby gem, ‘win32/process’, this is used to run the popup clicker as a separate process that runs in the background. Once you have those functions in place you can simply call:
callPopupKillerIE #Starts the IE popup killer
#Some watir code that results in a popup#
killPopupKiller #Kills the popup killer process, so that you do not end up with 5 of them running!
Friday, April 9, 2010
Watir: Introduction: What is Watir
Introduction
"Watir" (pronounced water) stands for "Web Application Testing in Ruby". Watir is an automated test tool which uses the Ruby scripting language to drive the Internet Explorer web browser. Watir is a toolkit for automated tests to be developed and run against a web browser.What Does Watir Work With?
Watir will drive web applications that are served up as HTML pages in a web browser. Watir will not work with ActiveX plugin components, Java Applets, Macromedia Flash, or other plugin applications. To determine whether Watir can be used to automate a part of a web application, right click on the object and see if the View Source menu option is available. If you can view the HTML source, that object can be automated using Watir.Prerequisites
To use the tool, you should have a basic understanding of:- HTML: This is a basic HTML tutorial.
- Programming: You should understand programming basics, including variables and simple control structures like "for" loops and "if" statements.
- Ruby: You do not need to know how to program in Ruby to get started with Watir, but you should learn some Ruby if you really want to get the most out of Watir
- Check out the Ruby Cheat Sheet for basic Ruby information.
- Microsoft has a toolbar for Internet Explorer which can be useful in navigating the DOM for pages that you're looking to automate.
Watir: Install Ruby: How to Installed Ruby ?
- Log in as administrator.
- Download the One-Click Ruby Installer for Windows (v.1.8.6-26) from the Ruby One Click Installer Page .
We recommend using the latest version of Ruby 1.8.6 with Watir 1.6.
Watir's modal dialog support in Watir 1.5 required Ruby 1.8.2. This is no longer true and this feature now requires Ruby 1.8.6. - Run it (leave all choices at the default).
- You have installed Ruby.
- Installing Ruby 1.9.1
Install the lastest 1.9.1 RubyInstaller and development kit from here: http://rubyforge.org/frs/?group_id=167
(at the time of writing it is this: rubyinstaller-1.9.1-p243-rc1.exe)
Note: The Ruby path is not set by default but there is an option to set it in the installer
Type ruby -v in the command line which should return
ruby 1.9.1p243 (2009-07-16 revision 24175) [i386-mingw32]
You can have >1 versions of Ruby installed, but the first that is found in the path is used.
Download 7-zip www.7-zip.org and unzip the devkit to here C:\ruby19
Watir: Install Watir: How to install Watir?
nstalling from behind a proxy
If you are installing from behind a proxy, be sure to add the following to the end of any gem install or gem update command:
For example, if your proxy server was named proxy and it accepted connections on port 8000, your addition to the command line would be
Read the gem install documentation for more information on specifying the proxy.
Watir's support for Firefox also requires a plugin.
FireWatir Installation#InstalltheJSSHFirefoxExtension
http://intertwingly.net/blog/2008/11/23/RubyGems-1-3-1-on-Ubuntu-8-10
Type these commands at a command prompt:
Watir's support for Firefox also requires a plugin.
FireWatir Installation#InstalltheJSSHFirefoxExtension
If you are installing from behind a proxy, be sure to add the following to the end of any gem install or gem update command:
-p http://your-proxy-server-name:your-proxy-server-port-p http://proxy:8000Windows
Watir supports Internet Explorer 5.5, 6 and 7 on Windows 2000, XP, Server 2003 and Vista. Watir also supports Firefox 2 and 3.- Make sure you are logged in as administrator.
- Open command prompt and type:
gem update --system gem install watir
- Beginning with Watir 1.6.0 (Oct 2008), this installs drivers for both
IE and Firefox (FireWatir). Output should be something like this:
C:\Documents and Settings\Administrator\>gem install watir Successfully installed watir-1.5.x Installing ri documentation for watir-1.5.x... Installing RDoc documentation for watir-1.5.x...
- Watir's support for Firefox also requires a plugin.
FireWatir Installation#InstalltheJSSHFirefoxExtension
Mac
Type these commands at a command prompt:sudo gem update --system sudo gem install firewatir sudo gem install safariwatir
FireWatir Installation#InstalltheJSSHFirefoxExtension
Linux
To solve Ubuntu 8.10 gem hassle:http://intertwingly.net/blog/2008/11/23/RubyGems-1-3-1-on-Ubuntu-8-10
Type these commands at a command prompt:
sudo gem update --system sudo gem install firewatir
FireWatir Installation#InstalltheJSSHFirefoxExtension
| When you install Watir, you may get an error building the documentation for the Builder gem. You can safely ignore this error. |
watir:Run Unit Tests:How to run Unit test in Watir?
The unit tests don't work with the Watir 1.6 gem, as described below. Sorry.
You will need a development environment (Get the source code and unit tests from SVN) to run them.
Unit Tests
If you are following the Quick Start Guide, this section is not necessary to get up and running
To run the unit tests:
And press "F5"
You will need a development environment (Get the source code and unit tests from SVN) to run them.
Unit Tests
If you are following the Quick Start Guide, this section is not necessary to get up and running
Running the Unit Tests
After you have installed Ruby and Watir, you can run the unit tests to verify the installation.To run the unit tests:
- If you have installed Ruby in its default folder of "C:\Ruby" then in "SciTE" goto:
C:\ruby\lib\ruby\gems\1.8\gems\watir-1.5.x\unittests\core_tests.rb
- The tests should all run and pass.
- If you receive any errors, try updating your gems with:
gem update
Having Problems?
If you are using Windows XP with Service Pack 2 or Windows Server 2003, several tests will fail unless you enable active content. To fix this:- From the browser, select Tools > Internet Options
- Select the Advanced tab
- Under Security, check Allow active content to run in files on My Computer
- Click OK
Additional Problems
- If you have the google toolbar installed, you will need to turn off the popup blocker.
- If you are installing on a new system, you will get a dialog asking about auto-complete. You will have to answer this question before you can run the unit tests.
- The following gems must be installed. (These are installed when you install the watir gem.)
- activesupport
- user-choices
Install Browser Developer Toolbar
To view details of elements in your web application, it is recommended to use a developer toolbar as it will provide element inspection functionality. These quickly show you the element attributes and properties you need to know to automate them with Watir.
There are two recommended packages depending on whether you prefer Internet Explorer or Firefox.
There are two recommended packages depending on whether you prefer Internet Explorer or Firefox.
| Browser | Developer Toolbar |
|---|---|
| Internet Explorer | IE Developer Toolbar |
| Firefox | Firebug |
Ruby Cheat Sheet
This cheat sheet describes Ruby features. It's not a reference to the language. You do have a reference to the language: the full text of Programming Ruby: The Pragmatic Programmer's Guide is installed with Ruby. Select start -> All Programs -> Ruby -> Ruby Documentation -> RubyBook Help.
Now the variable number has the value 5. Ordinary variables begin with lowercase letters. After the first character, they can contain any alphabetical or numeric character. Underscores are helpful for making them readable:
A variable's value is gotten simply by using the name of the variable. The following has the value 10:
Strings are objects in Ruby. This means that they have methods. (In fact everything in Ruby is an object.)
A method call looks like this:
A method is a function for a particular type of object. In this case, the thing before the period is the object, in this case a string simon. The method is upcase. It capitalizes its object.
Like functions, methods can have arguments.
This method is true if its argument book is a substring of bookkeeper.
You can also concatenate strings using the + operator.
Put the if, else, and end on separate lines as shown. You don't have to indent, but you should.
Functions can return values, and those values can be assigned to variables. The return value is the last statement in the definition. Here's a simple example:
Note that we didn't need to say five(), as is required in some languages. You can put in the parentheses if you prefer.
The value of the last statement is always the value returned by the function. Some people like to include a return statement to make this clear, but it doesn't change how the function works. This does the same thing:
Here's a little more complicated example:
To use it in another script, we must require it:
This will cause Ruby to search its loadpath for a file named mathplus.rb. (It will automatically add the .rb.) It will search the directories that normally contain Ruby libraries, as well as the current directory (typically the same directory as your script).
If your library is in a location that Ruby doesn't know about, you will need to change the loadpath:
Make sure you include this line before you require libraries in it.
This is an array with two numbers in it:
This is an array with two numbers and a string in it. You can put anything into an array.
Here's how you get something out of an array:
Here's how you get the last element out:
Here's another way to get the last element:
Here's how you change an element:
How long is an array?
Here's how you tack something onto the end of an array:
Here's one way to print the numbers from one to 10:
And here's another:
The part between the do and the end is called a block. You can replace the do and end with braces:
The 1..10 is a range, which works like an array of the numbers from 1 to 10. The each is a method that iterates through each element of the range. It is called an iterator.
This prints each value of an array:
What if you want to transform each element of an array? The following capitalizes each element of an array.
Regular expressions are characters surrounded by // or %r{}. A regular expression is compared to a string like this:
Most characters in a regular expression match the same character in a string. So, these all match:
This also matches:
Notice that the regular expression can match anywhere in the string. If you want it to match only the beginning of the string, start it with a caret:
If you want it to match at the end, end with a dollar sign:
If you want the regular expression to match any character in a string, use a period:
There are a number of other special characters that let you amazing and wonderful things with strings. Ruby uses the standard syntax for regular expressions used in many scripting languages. See Programming Ruby for more information about regular expressions.
What happens if there's no match? Type this:
and the result will be nil, signifying no match. You can use these results in an if, like this:
In Ruby, anything but the two special values false and nil are considered true for purposes of an if statement. So match results like 0 and 10 count as true.
Here's how to search an array for an element:
The detect method takes a block as an argument. This block returns true if the first argument starts with an r. (Actually it returns 0, which counts as true.) The detect method itself returns the first element for which its block is true.
When blocks are longer than one line, they are usually written using do and end. This is another way of writing the same code:
Here's how you create a dictionary:
Here's how you associate a value with a key:
Here's how you retrieve a value, given a key:
Here's how you ask how many key/value pairs are in the dictionary:
What values does a dictionary have?
What keys does it have?
You can do this
And this:
Comments
In Ruby, any text on a single line that follows a # is a comment, and is ignored by the Ruby interpreter at run time.# comment
Function Calls
Parentheses can sometimes be omitted. If you're not sure whether they're required, put them in. To be safe, put them in whenever the call is at all complicated. Even one as simple as this.puts "hello"
puts("hello")
assert_equal(5, number)Variables
Ordinary (local) variables are created through assignment:number = 5
this_is_my_variable = 5
number + this_is_my_variable # returns 10
Strings, Objects and Methods
Strings are sequences of text in quotation marks. You can use single or double quotes.name = 'simon' name = "simon"
A method call looks like this:
"simon".upcase # returns "SIMON"
Like functions, methods can have arguments.
"bookkeeper".include?('book') # returns trueYou can also concatenate strings using the + operator.
"dog" + "house" # returns "doghouse"
Conditionals (if)
if number == 5 puts "Success" # "Success" is a string. Strings can be surrounded with single or double quotes. else puts "FAILURE" end
Function Definitions
def assert_equal(expected, actual)
if expected != actual
puts "FAILURE!"
end
enddef five # note that no parentheses are required 5 end box = five # box's value is 5
The value of the last statement is always the value returned by the function. Some people like to include a return statement to make this clear, but it doesn't change how the function works. This does the same thing:
def five return 5 end
def make_positive(number)
if number < 0
-number
else
number
end
end
variable = make_positive(-5) # variable's value is 5
variable = make_positive(five) # variable's value is 5Libraries
Libraries contain functions or methods that can be used in many Ruby programs. Suppose we store the make_positive function defined above in a file called mathplus.rb.To use it in another script, we must require it:
require 'mathplus'
If your library is in a location that Ruby doesn't know about, you will need to change the loadpath:
$LOAD_PATH << 'c:/my_lib/'
Arrays
This is an array with nothing in it:[]
[1, 2]
[1, 'hello!', 220]
array = [1, 'hello', 220] array[0] # value is 1
array[2] # value is 220
array.last # value is 220
array[0]= 'boo!' # value printed is 'boo!' # array is now ['boo', 'hello', 220]
array.length # value is 3
array.push('fred') # array is now ['boo', 'hello', 220, 'fred']Iteration
When you do something multiple times, it is called iteration. There are many ways to do this. The following will print hello five times:5.times do puts 'hello' end
for x in 1..10 do puts x end
(1..10).each do |x| puts x end
(1..10).each { |x| puts x }This prints each value of an array:
["a", "b", "c"].each { |x| puts x }["hi", "there"].collect { |word| word.capitalize } # The result is ["Hi", "There"].Regular Expressions
Regular expressions are a useful feature common to many languages. They allow you to match patterns in strings.Regular expressions are characters surrounded by // or %r{}. A regular expression is compared to a string like this:
regexp =~ string
/a/ =~ 'a string' /a/ =~ 'string me along'
/as/ =~ 'a string with astounding length'
/^as/ =~ 'alas, no match'
/no$/ =~ 'no match, alas'
/^.s/ =~ "As if I didn't know better!"
Truth and Falsehood
If you try the examples above, you'll see that the ones that match print a number. That's the position of the first character in the match. The first expression (/a/ =~ 'a string') returns 0. (Ruby, like most programming languages, starts counting with 0.) The second returns 10.What happens if there's no match? Type this:
/^as/ =~ 'alas, no match'
if /^as/ =~ some_string puts 'the string begins with "as".' end
Blocks
A block is like a function without a name. It contains a set of parameters and one or more lines of code. Blocks are used a lot in Ruby. Iterators like each use blocks.Here's how to search an array for an element:
gems = ['emerald', 'pearl', 'ruby']
gems.detect { |gem| /^r/ =~ gem } # returns "ruby" When blocks are longer than one line, they are usually written using do and end. This is another way of writing the same code:
gems.detect do |gem| /^r/ =~ gem end
Dictionaries
A dictionary lets you say "Give me the value corresponding to key." Dictionaries are also called hashes or associative arrays.Here's how you create a dictionary:
dict = {}dict['bret'] = 'texas' # looks a lot like an array, except that the key doesn't have to be a number.
dict['bret'] # value is 'texas'.
dict.length # value is 1
dict.values # value is the Array ['texas'].
dict.keys # value is the Array ['bret'].
Expression Substitution
Expression substitution evaluates an expression within a string:You can do this
name = "Aidy"
puts "My name is: #{name}"
=> My name is: Aidyputs "The sum of four times four is: #{4*4}"
=> The sum of four times four is: 16Example Test Case
Google Test Search
This document walks through a very simple test case:. To begin, open it in a text editor. If you do not have that file, download it from . To open it with SciTE, simply right-click the file in Windows Explorer, and select Edit from the popup menu.The format of this example will be to show the Ruby test case scripting code in a box as you would see it in a text editor, with an explanation after it.
Getting Started
Open Internet Explorer, and try out the test case manually on your own:- go to the Google home page
- enter pickaxe in the search text field
- click the Google Search button
Expected Result
A Google page with results should be shown. Programming Ruby should be high on the list.Once you have tried the test case out manually, it's time to automate the test case using Watir. Return to the Google home page and view the page source: right mouse click > View Source. Now you can follow along and see how to automate this test with Watir based on the HTML tags in the Google search web application.
Section 1: Comments
Test cases should be commented, just as program code should be commented. In Ruby, any text on a single line that follows a # is a comment, and is ignored by the Ruby interpreter at run time.What you see in the text editor:
#-------------------------------------------------------------# # Demo test for the Watir controller. # # Simple Google test written by Jonathan Kohl 10/10/04. # Purpose: to demonstrate the following Watir functionality: # * entering text into a text field, # * clicking a button, # * checking to see if a page contains text. # Test will search Google for the "pickaxe" Ruby book. #-------------------------------------------------------------#
Section 2: Includes
To use Watir, or any other library in our test case, requires us to tell the program where to find the library.What you see in the text editor:
# the Watir controller require "watir"
Section 3: Declare Variables
If we are going to use something in our script more than once, or something that could change, we can declare it as a variable and reuse it throughout the script. Some objects we can use for testing tend to change, such as URLs for applications we are testing. In this script, we assign the test URL as a variable. If it changes, we only have to change it in one place.What you see in the text editor:
# set a variable test_site = "http://www.google.com"
Section 4: Open an Internet Explorer Browser
To begin driving Internet Explorer, we need to tell Watir to open an instance for testing.What you see in the text editor:
# open the IE browser ie = Watir::IE.new
Section 5: Interacting With Google
Now we are ready to start automating the steps we ran manually using Watir.Beginning the test case
What you see in the text editor:# print some comments puts "Beginning of test: Google search."
Step 1: Go to the Google site
This test case follows a pattern of printing out what we intend Watir to do on a web application, followed by the Watir scripting code to carry out that action. This is a style of test case development that is useful for tracking down test case failures quickly.What you see in the text editor:
puts " Step 1: go to the test site: " + test_site ie.goto test_site
Step 2: Enter Search Term pickaxe in the search field
We need to enter the term to search in the text field on the Google home page.What you see in the web browser:
puts " Step 2: enter 'pickaxe' in the search text field." ie.text_field(:name, "q").set "pickaxe" # "q" is the name of the search field
This is the tag in the HTML source with the name attribute we used:
"Google Search" value="">Step 3: Click the Google Search button
We need to click the search button to activate the Google Search functionality.What you see in the web browser:
puts " Step 3: click the 'Google Search' button." ie.button(:name, "btnG").click # "btnG" is the name of the Search button
This is the tag in the HTML source with the name attribute we used:
"Google Search">Section 6: Evaluating the Results
The Expected Result
This test case prints out what the Expected Result should be prior to the test case using Watir to evaluate the results.What you see in the text editor:
puts " Expected Result:" puts " A Google page with results should be shown. 'Programming Ruby' should be high on the list."
Verify Results
Using Watir and a little Ruby, we can evaluate the results to verify whether the test case passed or failed.puts " Actual Result:" if ie.text.include? "Programming Ruby" puts " Test Passed. Found the test string: 'Programming Ruby'. Actual Results match Expected Results." else puts " Test Failed! Could not find: 'Programming Ruby'." end
- The first line prints out the Actual Result heading to the screen.
- The second line gets the text of the page and then calls the include? method to determine whether Programming Ruby appears on the first page.
- Using an if statement, we evaluate whether the include? method was true or false.
- If include? returns true (or actually anything but false), the text Programming Ruby appears. The test case passes and we print the Test Passed. message.
- Else, if include? returns false, the text Programming Ruby does not appear. The test case fails and we print the Test Failed! message.
- We close the conditional if section with an end statement.
End of Test Case
What you see in the text editor:puts "End of test: Google search."
Developing Test Cases
The goal of this user guide is to help you get started writing test cases quickly. Each section describes the methods for driving a web application. Select the ones you need for each page of your web application based on the content of each page in the application.
Plan what you need to get Watir to do before you begin scripting. Open your web browser with the application under test in front of you, and pay close attention to the objects on that page. What text fields require entries? What buttons need to be pushed? What links need to be clicked on? It sometimes helps to write out the steps it will take to exercise a test first, and then filling in the Watir scripting code to satisfy each of those steps.
To start developing a test:
Plan what you need to get Watir to do before you begin scripting. Open your web browser with the application under test in front of you, and pay close attention to the objects on that page. What text fields require entries? What buttons need to be pushed? What links need to be clicked on? It sometimes helps to write out the steps it will take to exercise a test first, and then filling in the Watir scripting code to satisfy each of those steps.
To start developing a test:
- Open your text editor.
- Name your test file with a .rb (Ruby) extension (like test.rb).
- Provide your new test file with access to the Watir tool by entering this statement at the beginning of your test script:
require 'watir'
- Open Internet Explorer and navigate to the application you wish to test.
- Interact with it to design your test case.
- Type the corresponding Watir methods into your test script.
- Verify the results.
IE:Internet Explorer Developer Toolbar: What is IE?
Microsoft has an extension for Internet Explorer (link does not work with Firefox) that is a great addition to any tester's toolkit and is a great help when scripting web pages using Watir. This works on the DOM in the same manner that Watir does. You can explore the DOM, find elements by clicking on them and more. It's a highly recommended tool to use while writing Watir scripts.
The Internet Explorer Developer Toolbar provides several features for exploring and understanding Web pages. These features enable you to:
Navigate to Google Search, and you should see something like the following.

In this case you can see the name attribute of the field to use in your scripts. Watir can use different attributes of a tag to manipulate that object, so it is important to know what they are. In some cases the attributes are not explicit in the tag such as the text attributes.
The Internet Explorer Developer Toolbar provides several features for exploring and understanding Web pages. These features enable you to:
- Explore and modify the document object model (DOM) of a Web page.
- Locate and select specific elements on a Web page through a variety of techniques.
- View HTML object class names, ID's, and details such as link paths, tab index values, and access keys.
- Outline tables, table cells, images, or selected tags.
- Display image dimensions, file sizes, path information, and alternate (ALT) text.
- Selectively clear the browser cache and saved cookies. Choose from all objects or those associated with a given domain.
- Find the style rules used to set specific style values on an element.
- View the formatted and syntax colored source of HTML and CSS.
- Style Tracer: Right mouse click on a style value for an element and select Style Tracer to find the style rule that is effecting that value.
- View Source: View the formatted and syntax colored source of the original page, currently rendered page, element or element with the styles that are effecting it.
Navigate to Google Search, and you should see something like the following.
In this case you can see the name attribute of the field to use in your scripts. Watir can use different attributes of a tag to manipulate that object, so it is important to know what they are. In some cases the attributes are not explicit in the tag such as the text attributes.
Interacting With a Web Page
You will notice we've chosen to name the variable name ie used in Watir test scripts for the Internet Explorer browser. You could call it whatever you wish, but we use ie for ease of use. This variable tells the Watir library to exercise test scripts against an instance of the Internet Explorer web browser.
In Ruby, think of programming in terms of objects and messages. Watir was also developed with objects and messages in mind. If you think of the ie variable as an object, you can send messages to it. Think of objects as nouns. When you start up Internet Explorer, the operating system starts the program which creates an instance of the Internet Explorer web browser. You refer to this Internet Explorer browser instance as a thing. If you send a message to that object, it will respond to that message if it recognizes it.
Think of the messages as verbs. In Ruby, you send a message to an object by separating the object you are calling from the message you are sending to it with a dot. For example:
would tell the object dog that it must bark.
This isn't very specific though. What dog should bark? In the Watir world, you could identify the test area to be our yard. Like ie, treat it as an object with attributes containing other objects with attributes. For example, in our yard, there are two dogs: Heidi and Megabyte. Each of these dog objects have attributes that identify them. They have names, breeds, shapes and sizes and colors. To be more specific, and interacting with them the Watir way, you could send the message bark to the dog Heidi like this:
This says in Watir syntax: in the yard, identify the dog Heidi by her name attribute, and send her the bark message. The expected outcome would be Heidi responding to the message by barking.
When you develop test scripts with Watir, you interact with objects on a web page by sending them messages. Like the yard example, the Internet Explorer browser itself contains objects. You can access these objects within an Internet Explorer browser instance by identifying them by different attributes. Just like in the dog example, above, you must be very specific when you send messages to objects on a web page. You must also be able to identify objects on a web page by using a variety of different attributes due to the diversity in how tags are declared by different application developers. With Watir, identify objects and send them messages by using the dot notation. For example:
narrows down the type of object to send a message to.
identifies the object on the page as a button within the instance of Internet Explorer (ie) that has the value attribute (caption) Click Me. When you send the message (the verb) click, Watir interprets and tells Internet Explorer to click.
In Ruby, think of programming in terms of objects and messages. Watir was also developed with objects and messages in mind. If you think of the ie variable as an object, you can send messages to it. Think of objects as nouns. When you start up Internet Explorer, the operating system starts the program which creates an instance of the Internet Explorer web browser. You refer to this Internet Explorer browser instance as a thing. If you send a message to that object, it will respond to that message if it recognizes it.
Think of the messages as verbs. In Ruby, you send a message to an object by separating the object you are calling from the message you are sending to it with a dot. For example:
dog.bark
This isn't very specific though. What dog should bark? In the Watir world, you could identify the test area to be our yard. Like ie, treat it as an object with attributes containing other objects with attributes. For example, in our yard, there are two dogs: Heidi and Megabyte. Each of these dog objects have attributes that identify them. They have names, breeds, shapes and sizes and colors. To be more specific, and interacting with them the Watir way, you could send the message bark to the dog Heidi like this:
yard.dog(:name, "Heidi").bark
When you develop test scripts with Watir, you interact with objects on a web page by sending them messages. Like the yard example, the Internet Explorer browser itself contains objects. You can access these objects within an Internet Explorer browser instance by identifying them by different attributes. Just like in the dog example, above, you must be very specific when you send messages to objects on a web page. You must also be able to identify objects on a web page by using a variety of different attributes due to the diversity in how tags are declared by different application developers. With Watir, identify objects and send them messages by using the dot notation. For example:
ie.button
ie.button(:value, "Click Me").click
What is Watir Syntax?
The Watir syntax is shown later with three views. One is the view that we see objects on a web page while viewing them in a web browser. The next view is an example of the Watir code that would be needed to automate an action using that web page object. The third view is the object on the web page shown in its HTML form. This is the way it looks when we view the source of a web page, or open the file in a text editor.
This allows our test script to use the Watir tool.
Watir sends a message to Internet Explorer, telling to create a new instance of itself, and assigns that instance to ie.
To create an instance of Internet Explorer and navigate to the site with one statement:
Watir uses the start method to both create a browser instance and navigate to a site.
In the example above, enter in your application's URL in place of mytestsite.
Watir sends the goto message to Internet Explorer, telling it to enter the address you entered as a method argument in the Address bar, and to direct the browser to that site.
Require the Watir Tool
To use the Watir tool, first enter the following in your test script:require 'watir'
Create a Test Instance of Internet Explorer
To create a test instance of Internet Explorer, enter the following in your test script:ie = Watir::IE.new
To create an instance of Internet Explorer and navigate to the site with one statement:
ie = Watir::IE.start("http://mytestsite")Site Navigation
To direct your test script to the web application you are testing, enter the URL in this command:ie.goto("http://mytestsite")Watir sends the goto message to Internet Explorer, telling it to enter the address you entered as a method argument in the Address bar, and to direct the browser to that site.
Subscribe to:
Posts (Atom)