Skip to end of metadata
Go to start of metadata

There are many ways you could run tests in parallel with Ruby, but this example will use RSpec, the behavior-driven development (BDD) framework for Ruby. 

  1. Add the RSpec and ParallelTests gems into your Gemfile, then run bundle install.

    gem "rspec", "~> 3.0.0"
    gem "parallel_tests", "~> 1.6.1
  2. Create a spec directory in your project's root directory.
  3. In the spec directory, create a file called sauce_driver.rb, which will encapsulate the behaviour we need to create Selenium drivers with Sauce Labs.

    You can also clone this file directly from GitHub.

    require "selenium/webdriver"
    
    module SauceDriver
      class << self
        def sauce_endpoint
          "https://YOUR_SAUCE_USERNAME:YOUR_SAUCE_ACCESS_KEY@ondemand.saucelabs.com:443/wd/hub"
        end
    
        def caps
          caps = {
            :platform => "Mac OS X 10.9",
            :browserName => "Chrome",
            :version => "31"
          }
        end
    
        def new_driver
          Selenium::WebDriver.for :remote, :url => sauce_endpoint, :desired_capabilities => caps
        end
      end
    end

     

    Now you need to make RSpec create a new driver for each spec. The cleanest way to do this is by defining an around hook, which will be run, naturally, around every spec. 

  4. Create a file in the spec directory called spec_helper.rb
    This file will be require `d by every spec you create, as this is where, by convention, any setup code is placed.

    You can also clone this file directly from GitHub.

    require "rspec"
    require_relative "sauce_driver"
     
    RSpec.configure do |config|
      config.around(:example, :run_on_sauce => true) do |example|
        @driver = SauceDriver.new_driver
        begin
          example.run
        ensure
          @driver.quit
        end
      end
    end

    On line 5 you set up a new block of code to be run around every example tagged with :run_on_sauce => true. This lets you have non-Selenium tests that don't spin up Selenium sessions. You have to make sure you include :run_on_sauce on all your Selenium tests, though!

    On line 6 you use the SauceDriver class you set up earlier to create a new Selenium driver, 'pointed' at Sauce Labs. Then, on line 8, you run the example. On lines 9 - 11 we call quit on the Selenium session; This is done in an ensure block so that each test always closes off its driver, even if something goes wrong.

Now you have RSpec set up to create drivers and close them down. Your next question might be, "How do I use these drivers?" Super simple. Because driver is an instance variable, and the around block runs in the context of the spec, it can use the driver directly. Consider this example spec.

You can also clone this file directly from GitHub.

require_relative "spec_helper"
 
describe "Google's Search Functionality" do
  it "can find search results", :run_on_sauce => true do
    @driver.manage.timeouts.implicit_wait = 10
    @driver.navigate.to "http://www.google.com"
 
    raise "Unable to load Google." unless @driver.title.include? "Google"
 
    query = @driver.find_element :name, "q"
    query.send_keys "Sauce Labs"
    query.submit
 
    puts @driver.title
  end
end

On line 1 you require spec_helper. Then, on line 4 you add :run_on_sauce => true to make sure the around block runs. You can use the created driver, @driver, without any further setup, and you don't have to do anything to close it off either. This means you're much less likely to forget to do so when you write more tests.

Now, parallel testing! If you go ahead and create some more specs like this one (you can copy google_spec.rb into other files in the spec directory, just make sure the filenames end in spec.rb), then run the specs from your project root directory with:

bundle exec parallel_rspec -n 2 spec/

You should be able to log into Sauce Labs and see your tests running in parallel. If your account has more than two concurrency slots (meaning, you have a paid account), you can increase the number after -n to match your concurrency, and parallel_tests will spin up more tests at once.

  • No labels