Selenium is a great tool for web acceptance testing, but working on tests can be laborious. In addition to the general slowness of actually testing through the browser, starting a SeleniumDriver takes about 6 seconds on my MacBook.
require "rubygems"
gem "Selenium"
require "selenium"
benchmark = Benchmark.measure do
driver = Selenium::SeleniumDriver.new(
"localhost", 4444,
"*firefox", "http://localhost:3000"
)
driver.start
driver.stop
end
benchmark.to_s
#=> " 0.000000 0.000000 0.000000 ( 6.294741)"
If the selenium driver could stay open between test runs, running a test could be much faster. Fortunately, DRb makes this easy. Here are the rough steps.
First, start a SeleniumDriver and place it in a DRb service.
require "rubygems"
gem "Selenium"
require "selenium"
require "drb"
SERVER = "druby://:51785"
driver = Selenium::SeleniumDriver.new(
"localhost", 4444,
"*firefox", "http://localhost:3000"
)
driver.start
DRb.start_service SERVER, driver
puts "Ready"
DRb.thread.join
The DRb.thread.join call at the end of this script means the script won't exit. Run it from a terminal, use Ctrl+C to stop it.
The next step is to use this instance when running tests. DRb provides a class that functions as a proxy to the object running in the server. In this case, that's the selenium driver.
DRb.start_service
driver = DRbObject.new(nil, SERVER)
class << driver
# make sure type hits method_missing to delegate to driver
undef_method :type
end
Using the DRbObject as a proxy to the SeleniumDriver requires hacking the type method to make sure it delegates properly.
Here's the benchmark for this version:
benchmark = Benchmark.measure do
DRb.start_service
driver = DRbObject.new(nil, SERVER)
class << driver
# make sure type hits method_missing to delegate to driver
undef_method :type
end
end
benchmark.to_s
#=> 0.000000 0.000000 0.000000 ( 0.070634)
The time to start the driver is now negligible.
I've been using this for a few days, and it is working well. If you actually want to try this, here are a couple tweaks to the code that you'll want to make.
To stop the SeleniumDriver when stopping the process, wrap DRb.thread.join like this:
begin
DRb.thread.join
rescue Interrupt
begin
puts "Stopping..."
driver.stop
rescue Exception
puts "failed stopping selenium driver"
end
end
DRbObject does not check the connection when it's first initialized. You may want to force it to check the connection by doing something like this:
begin
DRb.start_service
driver = DRbObject.new(nil, SERVER)
driver.respond_to?(:anything?)
rescue DRb::DRbConnError
# do something
# fail over to non-DRb driver?
end
A call to respond_to? will check to see if the DRb server is available. You may want print out an informative message or fail over to using a non-DRb driver if it cannot connect.
No comments yet.
You must be logged in to add your own comment.