Skip to main content
Looking to test on every commit or PR? Introducing plans for high-scale testing on Chrome and Firefox. Read more

Run Tests in Parallel

A guide to running Ruby tests in parallel to achieve faster execution of builds.

On BrowserStack, you can run multiple Selenium Webdriver tests at the same time across various browser, device and OS combinations. This is called Parallel Testing. Parallel Testing gives you the same benefits as running a multi-threaded application.

With Parallel Testing, you can run the same test on different browser/device combinations i.e. cross-browser testing, or run different tests on the same or different browser/device combinations. Parallel Testing will help you reduce the run time of your test suite, resulting in faster build times and faster releases.

You can start testing in parallel using one of the popular test frameworks which work with Ruby and Selenium or you can also choose to run tests in parallel without a framework. We have provided getting started guides on some of the popular frameworks below:

Run tests in parallel without a framework

You can achieve parallel testing in multiple ways even if you are not using one of the popular test frameworks which has feature for enabling parallel testing. We show two such ways below but this is not an exhaustive list:

Using a multi-threaded program

The following sample script shows a multi-threaded Ruby program. These are the salient points of the script:

  • The same script is run across five different browser and OS combinations viz. Chrome on Win10, Firefox on Win10, Safari on MacOS, Edge on Win10, Chrome with the latest available beta version on Win10.
  • The run_session function takes capabilities as arguments and executes the same test script on each set of the browser/OS combinations.
require 'rubygems'
require 'selenium-webdriver'

def run_session(browser, version, os, os_version, device, realMobile, javascriptEnabled, test_name, build_name)
    caps = Selenium::WebDriver::Remote::Capabilities.new
    caps['browser'] = browser
    caps['os_version'] = os_version
    caps['os'] = os
    caps['browser_version'] = version
    caps['device'] = device
    caps['realMobile'] = realMobile
    caps['javascriptEnabled'] = javascriptEnabled
    caps['name'] = test_name # test name
    caps['build'] = build_name # CI/CD job or build name

    driver = Selenium::WebDriver.for(:remote,
    :url => "https://YOUR_USERNAME:YOUR_ACCESS_KEY@hub-cloud.browserstack.com/wd/hub",:desired_capabilities => caps)
    begin
        # opening the bstackdemo.com website
        driver.navigate.to "https://bstackdemo.com/"
        wait = Selenium::WebDriver::Wait.new(:timeout => 10) # seconds
        wait.until { !driver.title.match(/StackDemo/i).nil? }

        # getting name of the product available on the webpage
        product = driver.find_element(:xpath, '//*[@id="1"]/p')
        wait.until { product.displayed? }
        product_text = product.text

        # waiting until the 'Add to Cart' button is displayed on webpage and then clicking it
        cart_btn = driver.find_element(:xpath, '//*[@id="1"]/div[4]')
        wait.until { cart_btn.displayed? }
        cart_btn.click

        # waiting until the Cart pane appears
        wait.until { driver.find_element(:xpath, '//*[@id="__next"]/div/div/div[2]/div[2]/div[2]/div/div[3]/p[1]').displayed? }
          
        # getting name of the product in the cart
        product_in_cart = driver.find_element(:xpath, '//*[@id="__next"]/div/div/div[2]/div[2]/div[2]/div/div[3]/p[1]')
        wait.until { product_in_cart.displayed? }
        product_in_cart_text = product_in_cart.text

        # checking if the product has been added to the cart
        if product_text.eql? product_in_cart_text
            # marking test as 'passed' if the product is successfully added to the cart
            driver.execute_script('browserstack_executor: {"action": "setSessionStatus", "arguments": {"status":"passed", "reason": "Product has been successfully added to the cart!"}}')
        else
            # marking test as 'failed' if the product is not added to the cart
            driver.execute_script('browserstack_executor: {"action": "setSessionStatus", "arguments": {"status":"failed", "reason": "Failed to add product to the cart"}}')
        end

    # marking test as 'failed' if test script is unable to open the bstackdemo.com website
    rescue
        driver.execute_script('browserstack_executor: {"action": "setSessionStatus", "arguments": {"status":"failed", "reason": "Some elements failed to load"}}')
    end
    driver.quit
end

t1 = Thread.new{run_session("Chrome", "latest", "Windows", "10", nil, nil, nil, "Sample test on Chrome-Windows", "Parallel-build-ruby")}
t2 = Thread.new{run_session("Firefox", "latest", "OS X", "Monterey", nil , nil, nil,"Sample test on Firefox-macOS", "Parallel-build-ruby")}
t3 = Thread.new{run_session("Safari", "latest", "OS X", "Catalina", nil, nil, nil, "Sample test on Safari-macOS", "Parallel-build-ruby")}
t4 = Thread.new{run_session("Android", "latest", nil, nil, "Samsung Galaxy S20", "true", "true", "Sample test on Android", "Parallel-build-ruby")}
t5 = Thread.new{run_session("iPhone", "latest-beta", nil, "14", "iPhone 12 Pro Max", "true", "true", "Sample test on iPhone", "Parallel-build-ruby")}

t1.join()
t2.join()
t3.join()
t4.join()
t5.join()

Using a multi-threaded program and using ThreadPoolExecutor to manage threads

In case of the above implementation, all the threads are dispatched at the same time. You can also manage the dispatching of threads by applying additional conditions, but, in that case, you would have to manually keep track of which thread has completed its execution and depending on that, you will be required to spawn new threads keeping in mind you do not exceed the limit of parallel tests that is supported by your BrowserStack account.

You can choose to not manage the threads manually and use the Ruby ThreadPool to do the same for you by following the steps mentioned in the ruby thread pool guide

Conclusion

You can run parallel tests on BrowserStack even if you are not using a testing framework by choosing one of the above-shown methods or even build your own logic in a shell script that spawns multiple parallel processes and run tests in parallel in those processes.

We're sorry to hear that. Please share your feedback so we can do better

Contact our Support team for immediate help while we work on improving our docs.

We're continuously improving our docs. We'd love to know what you liked






Thank you for your valuable feedback

Is this page helping you?

Yes
No

We're sorry to hear that. Please share your feedback so we can do better

Contact our Support team for immediate help while we work on improving our docs.

We're continuously improving our docs. We'd love to know what you liked






Thank you for your valuable feedback!

Talk to an Expert
Talk to an Expert