Integrating Robot Framework with Sauce OnDemand

Posted Nov 23rd, 2010

A mini revolution is happening in the automation space with a whole segment of tools designed to aid in the definition and execution of acceptance criteria. This is the ATDD (Acceptance Test Driven Development) realm and is populated by tools such as Cucumber, Robot Framework, JBehave, etc. This post, though, is not about how to use ATDD effectively in your organization, but rather how to integrate the Sauce OnDemand with Robot Framework.
Robot Framework has built-in support for Selenium through its SeleniumLibrary, which means that support is as simple as telling the script to execute in the cloud rather than locally. Thankfully, you can specify both host and port to the SeleniumLibrary when it is loaded.

Library  SeleniumLibrary  server_host=${SELENIUM HOST}  server_port=${SELENIUM PORT}

Of course, we need to set those variables somewhere. The easiest place would be in the Resource file as just hard-coded values, but that isn't something you often want to do. Typically you want to embed some type of method to decide whether to run the script locally or in the cloud. For that, it is better to use a Variable file since it is pure Python and lets you make decisions.

import sys

# default is to run locally
use_ondemand = "false"

# add the left/right decision
for arg in sys.argv:
    if arg.startswith("--ondemand"):
        parts = arg.split("=")
        use_ondemand = parts[1].lower()

if use_ondemand == "true":
    SELENIUM_PORT = "4444"
    SAUCE_USERNAME = "your-sauce-user"
    SAUCE_KEY = "your-sauce-key-here"
    SAUCE_OS = "Windows 2003"
    SAUCE_BROWSER = "firefox"
    SAUCE_VERSION = "3."
    SAUCE_NAME = "Robots everywhere!"
    BROWSER = '{"username": "%s", "access-key": "%s", "os": "%s", "browser": "%s", "browser-version": "%s", "name": "%s"}' % (SAUCE_USERNAME, SAUCE_KEY, SAUCE_OS, SAUCE_BROWSER, SAUCE_VERSION, SAUCE_NAME)
    SELENIUM_HOST = "localhost"
    SELENIUM_PORT = 4444
    BROWSER = "*firefox"

Nothing too surprising in here. The bulk of it is around creating the JSON string to send to Sauce Labs. In a real production example, the SAUCE_USERNAME and SAUCE_KEY values would be in an external file so they can be changed without affecting any of the variable files (and there could be many). Somehow iterating over permutations of SAUCE_OS, SAUCE_BROWSER and SAUCE_VERSION also holds promise, but I suspect that would involve writing a custom runner that forks separate Robot Framework processes. And while that might be fun, it's beyond the scope of this experiment.

The other part of interest, and why its a Variables file and not a Resource, is the left/right decision. In order to run the script in Sauce OnDemand, you provide the extra --ondemand=true argument. If absent, anything else for that flag will run locally.

With this in place, you can easily switch between running your Robot Framework acceptance tests locally or in Sauce OnDemand. Not only does this remove the need to manage your own grid of machines, but you get a video to share with the stakeholders who helped create the script in the first place. In fact, here is the video I created while writing this:

I have also made the source code available for this example on github.
Happy Robot-ing!

Written by

Adam Goucher