WatirGridParallel testing with Watir
AboutIn 2007, WatirGrid was created by Dane Avilla (brilliant!)In 2009, I packaged it as a gem , gave it a domainwatirgid....
If Watir is …
WatirGrid is …
WatirGridTakes all the advantages of Watir …                    //todoAnd multiplies its use in a distributed,parallel and...
WatirGrid is DistributedBuilt with standard DRb packages.Completely written in Ruby using corelibraries.Lets you control W...
WatirGrid is ParallelWatirGrid uses Threads to execute Watir testcases in parallel (sort of). Threads execute onremote Wat...
WatirGrid is Coordinated    Based on Rinda, the Ruby version of Linda    …    Linda is a model of coordination and communi...
WatirGrid is Free   Uses the BSD license[1][1] https://github.com/90kts/watirgrid/raw/master/LICENSE
Key TerminologyControllers implements a repository of tuples (tuplespace) that can be accessed concurrently. The controlle...
Controller + Providers
= the GridA loosely coupled, distributed workforce …
A Canned Example # 1If you haven‟t already …  gem install watirgridSomething simple …  require watirgrid  # Start a Contro...
What Just Happened?Started a Controller  DRb server was started on a random port  A Rinda Ring Server was started on port ...
What Just Happened?Created a Grid  We can see the previously registered tuple  represented as a hash. We‟ll be using the „...
Let‟s Use the Grid!Take the first (and only) browser on the gridand execute some Watir …# Take the first browser on the gr...
A Canned Example # 2Let‟s try with 2 providers …  require watirgrid  # Start a Controller using defaults  controller = Con...
Let‟s Use the Grid!Take all browsers on the grid in parallel usingThreads …browser_types = [:firefox, :chrome]threads = []...
Let‟s all Try .. 1I‟ll start a new Controller on port 12358  require watirgrid  # Start a Controller on port 12358  contro...
Let‟s all Try .. 2You start a Provider and register on myController  require watirgrid  provider = Provider.new(   browser...
Let‟s all Try .. 3!See if I can control the grid …  require watirgrid  # Start another Grid  grid = Watir::Grid.new  grid....
Security Considerations$SAFE = 1- poor man‟s paranoia- on latest branchACLs# Start a Controller with Access Control Listsc...
Performance           ConsiderationsYes, but does it scale? 50..nRuby threads 1.8 vs. native threads 1.9, truly parallel?G...
What‟$ Next?GRIDinit.com => a commercialimplementation of WatirGrid ondifferent cloud providers.Private alpha April – May,...
Questions?  About WatirGrid that is …
Upcoming SlideShare
Loading in …5
×

WatirGrid

2,499 views

Published on

An intro to testing in parallel with WatirGrid

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,499
On SlideShare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
26
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide
  • The standard Ruby library ships with a package known as DRb. You will sometimes see this package referred to as dRuby. No matter what you call the package, they both mean the same thing, Distributed Ruby. DRb is an incredibly easy package to learn and use. It has the benefits of being written completely in Ruby and using core libraries. It also offers advantages such as automatic selection of object transmission (either pass by value or pass by reference), reasonable speed, and the ability to run on any operat- ing system that runs Ruby (see Figure 1-1). DRb also allows you to write applications without a defined interface, which can make for faster development time.
  • When reviewing all of our DRb applications, you will notice, for a start, that we hardcoded IP addresses and ports into both our servers and clients. This type of tight coupling of applications can be problematic in both production and development. It can make fault tolerance difficult to code for. And what do you do if you need to start the service on a different machine that has a different IP address? We could also cre- ate and attempt to maintain complex configurations, but in the modern world of cloud computing IP addresses fluctuate every time you launch an instance. So, keep- ing those configuration files up to date would be extremely complicated and prone to error. That is certainly not an option.
  • require 'watirgrid'require 'pp'# Start a Controllercontroller = Controller.newcontroller.start# Start a Provider with SafariWatirprovider = Provider.new(:browser_type => 'safari')provider.startgrid = Watir::Grid.newgrid.start(:take_all => true)# Look at the Gridpp grid.browsers.first# Take the first browser on the grid and execute some Watirb = grid.browsers.first[:object].new_browserb.goto "http://altentee.com"b.close
  • require 'watirgrid'# Start a Controller using defaultscontroller = Controller.newcontroller.start# Start 2 Providers with WebDriver2.times do provider = Provider.new(:browser_type => 'webdriver') provider.startend# Start another Gridgrid = Watir::Grid.newgrid.start(:take_all => true)browser_types = [:firefox, :chrome]threads = [] grid.browsers.each_with_index do |browser, index| threads << Thread.new do b = browser[:object].new_browser(browser_types[index]) b.goto "http://altentee.com" sleep 5 b.close end endthreads.each {|thread| thread.join}
  • require 'watirgrid'# Start a Controller using defaultscontroller = Controller.newcontroller.start# Start 2 Providers with WebDriver2.times do provider = Provider.new(:browser_type => 'webdriver') provider.startend# Start another Gridgrid = Watir::Grid.newgrid.start(:take_all => true)browser_types = [:firefox, :chrome]threads = [] grid.browsers.each_with_index do |browser, index| threads << Thread.new do b = browser[:object].new_browser(browser_types[index]) b.goto "http://altentee.com" sleep 5 b.close end endthreads.each {|thread| thread.join}
  • require 'watirgrid'# Start a Controller using defaultscontroller = Controller.newcontroller.start# Start 2 Providers with WebDriver2.times do provider = Provider.new(:browser_type => 'webdriver') provider.startend# Start another Gridgrid = Watir::Grid.newgrid.start(:take_all => true)browser_types = [:firefox, :chrome]threads = [] grid.browsers.each_with_index do |browser, index| threads << Thread.new do b = browser[:object].new_browser(browser_types[index]) b.goto "http://altentee.com" sleep 5 b.close end endthreads.each {|thread| thread.join}
  • require 'watirgrid'# Start another Gridgrid = Watir::Grid.newgrid.start(:take_all => true)threads = [] grid.browsers.each do |browser| threads << Thread.new do b = browser[:object].new_browser b.goto("http://www.google.com") b.text_field(:name, 'q').set("watirgrid") b.button(:name, "btnI").click b.close end endthreads.each {|thread| thread.join}
  • $SAFE=1The environment variables RUBYLIB and RUBYOPT are not processed, and the current directory is not added to the path.The command-line options -e, -i, -I, -r, -s, -S, and -x are not allowed.Can't start processes from $PATH if any directory in it is world-writable.Can't manipulate or chroot to a directory whose name is a tainted string.Can't glob tainted strings.Can't eval tainted strings.Can't load or require a file whose name is a tainted string.Can't manipulate or query the status of a file or pipe whose name is a tainted string.Can't execute a system command or exec a program from a tainted string.Can't pass trap a tainted string.ACLsThis will bind the controller to the localhost (127.0.0.1) and deny all access to the controller by default, whilst allowing access from localhost only. The ACL constructor takes an array of strings. The first string of a pair is always “allow” or “deny”, and it’s followed by the address or addresses to allow or deny access.SSLusing Rinda over SSL has one small draw- back: we lose the ability for Rinda to dynamically bind to any available port. This affects only the server code. The client still is completely unaware of where the serv- ice is and uses the RingServer to find the service’s location.
  • The default ID converter, DRb::DRbIdConv, has one downside. If you’re not careful, referenced objects on the server can become garbage-collected and are no longer avail- able when the client tries to reference them. Although the client has a pointer to the local DRb::DRbObject it got from the server, the server itself may no longer have a pointer to the object that is referenced from the client. In that case it becomes eligible for garbage collection. One solution to this problem is to use the DRb::TimerIdConv class. A better approach to solve the garbage-collection problem lies in your architec- ture. Don’t take an object from the server and hold onto it in the client for any longer than you absolutely need to. Retrieve the object from the server, use it, and then get rid of it. If you want to make sure you have access to that same referenced object min- utes, hours, or days later, you should consider writing your own custom ID converter that stores your objects in something other than the ObjectSpace.
  • WatirGrid

    1. 1. WatirGridParallel testing with Watir
    2. 2. AboutIn 2007, WatirGrid was created by Dane Avilla (brilliant!)In 2009, I packaged it as a gem , gave it a domainwatirgid.com and have since maintained it … Tim Koopmans @90kts taking the FUD out of performance and test automation...
    3. 3. If Watir is …
    4. 4. WatirGrid is …
    5. 5. WatirGridTakes all the advantages of Watir … //todoAnd multiplies its use in a distributed,parallel and coordinated fashion…In other words “1 test case, many browsers”
    6. 6. WatirGrid is DistributedBuilt with standard DRb packages.Completely written in Ruby using corelibraries.Lets you control Watir objects remotely withtransmission passed by reference. I, [2011-03-24 13:45:06 #1057] INFO -- : DRb server started on : druby://192.168.1.6:50600 I, [2011-03-24 13:45:06 #1057] INFO -- : Ring server started on: druby://192.168.1.6:7647
    7. 7. WatirGrid is ParallelWatirGrid uses Threads to execute Watir testcases in parallel (sort of). Threads execute onremote Watir objects, offloading anyprocessing overheads … threads = [] grid.browsers.each_with_index do |browser, index| threads << Thread.new do ... end end threads.each {|thread| thread.join}
    8. 8. WatirGrid is Coordinated Based on Rinda, the Ruby version of Linda … Linda is a model of coordination and communication among several parallel processes operating upon objects stored in and retrieved from shared, virtual, associative memory. [1][1] Markoff, John (January 19, 1992). "David Gelernters Romance With Linda". The New York Times.
    9. 9. WatirGrid is Free Uses the BSD license[1][1] https://github.com/90kts/watirgrid/raw/master/LICENSE
    10. 10. Key TerminologyControllers implements a repository of tuples (tuplespace) that can be accessed concurrently. The controllerhosts the ring server which advertises these tuples acrossa grid network. Typically you will host one controller on acentral machine.Providers make remote Watir objects available to thetuple space hosted by the ring server. Typically you willhost one or many providers on your grid network, forexample, each PC may become a single provider of aWatir tuple in the form of an Internet Explorer, Firefox orSafari browser object.
    11. 11. Controller + Providers
    12. 12. = the GridA loosely coupled, distributed workforce …
    13. 13. A Canned Example # 1If you haven‟t already … gem install watirgridSomething simple … require watirgrid # Start a Controller controller = Controller.new controller.start # Start a Provider with SafariWatir provider = Provider.new(:browser_type => safari) provider.start # Create a Grid grid = Watir::Grid.new grid.start(:take_all => true)
    14. 14. What Just Happened?Started a Controller DRb server was started on a random port A Rinda Ring Server was started on port 7647 INFO -- : DRb server started on : druby://192.168.1.6:51163 INFO -- : Ring server started on: druby://192.168.1.6:7647Started 1 Provider (using SafariWatir) DRb server started on a random port The Ring Server was found on port 7647 A browser “tuple” was registed on the Ring Server INFO -- : DRb server started on : druby://192.168.1.6:51164 INFO -- : Ring server found on : druby://192.168.1.6:7647 INFO -- : New tuple registered : druby://192.168.1.6:7647
    15. 15. What Just Happened?Created a Grid We can see the previously registered tuple represented as a hash. We‟ll be using the „front object‟ provided … >> pp grid.browsers.first {:uuid=>"235fa1f0-37fd-012e-5bac-78ca394083a0", :browser_type=>"safari", :class=>:WatirProvider, :hostname=>"air.local", :object=>#<Watir::Provider:0x10166a240 @browser=Watir::Safari>, :name=>:WatirGrid, :architecture=>"universal-darwin10.0", :description=>"A watir provider"}
    16. 16. Let‟s Use the Grid!Take the first (and only) browser on the gridand execute some Watir …# Take the first browser on the grid and execute some Watirb = grid.browsers.first[:object].new_browserb.goto "http://altentee.com"b.close
    17. 17. A Canned Example # 2Let‟s try with 2 providers … require watirgrid # Start a Controller using defaults controller = Controller.new controller.start # Start 2 Providers with WebDriver 2.times do provider = Provider.new(:browser_type => webdriver) provider.start End # Start another Grid grid = Watir::Grid.new grid.start(:take_all => true)
    18. 18. Let‟s Use the Grid!Take all browsers on the grid in parallel usingThreads …browser_types = [:firefox, :chrome]threads = [] grid.browsers.each_with_index do |browser, index| threads << Thread.new do b = browser[:object].new_browser(browser_types[index]) b.goto "http://altentee.com" sleep 5 b.close end endthreads.each {|thread| thread.join}
    19. 19. Let‟s all Try .. 1I‟ll start a new Controller on port 12358 require watirgrid # Start a Controller on port 12358 controller = Controller.new(:ring_server_port => 12358) controller.start
    20. 20. Let‟s all Try .. 2You start a Provider and register on myController require watirgrid provider = Provider.new( browser_type => ‟firefox, # or ie, safari ... :ring_server_port => 12358) provider.start
    21. 21. Let‟s all Try .. 3!See if I can control the grid … require watirgrid # Start another Grid grid = Watir::Grid.new grid.start(:take_all => true) threads = [] grid.browsers.each do |browser| threads << Thread.new do b = browser[:object].new_browser b.goto("http://www.google.com") b.text_field(:name, q).set("watirgrid") b.button(:name, "btnI").click b.close end end threads.each {|thread| thread.join}
    22. 22. Security Considerations$SAFE = 1- poor man‟s paranoia- on latest branchACLs# Start a Controller with Access Control Listscontroller -a deny,all,allow,127.0.0.1 -H 127.0.0.1 -h 127.0.0.1HTTPS- not yet implemented
    23. 23. Performance ConsiderationsYes, but does it scale? 50..nRuby threads 1.8 vs. native threads 1.9, truly parallel?Garbage collection cleaning up referenced objects!Memory footprint of Controller? 100 Providers = 20MB
    24. 24. What‟$ Next?GRIDinit.com => a commercialimplementation of WatirGrid ondifferent cloud providers.Private alpha April – May,Public beta Junesupport@gridinit.comto participate …
    25. 25. Questions? About WatirGrid that is …

    ×