With Sauce Labs you can run automated tests of your web apps against a wide variety of device/operating system/browser combinations. This topic will provide you with basic information and code examples to get your Python tests up and running with Sauce.
Prerequisites
Quick Start
It's very easy to get your existing Python tests up and running on Sauce.
Set Sauce URL and Access Credentials
If you wanted to run a Selenium test on Selenium locally, you would initiate a driver for the browser you want to test against like this.
driver = webdriver.Firefox()
To run a test on a remote service like Sauce Labs, all you need to change is your driver
definition, make sure that the sauce_endpoint
variable includes your Sauce USERNAME
and ACCESSKEY,
and then pass it two parameters: command_executor
, which points to the Sauce cloud and uses your Sauce Labs authentication to log in, and desired_capabilties
, which specifies the browsers and operating systems to run the tests against.
# this is how you set up a test to run on Sauce Labs
desired_cap = {
'platform': "Mac OS X 10.9",
'browserName': "chrome",
'version': "31",
}
username = os.environ['SAUCE_USERNAME']
access_key = os.environ['SAUCE_ACCESS_KEY']
driver = webdriver.Remote(
command_executor='https://{}:{}@ondemand.saucelabs.com/wd/hub'.format(username, access_key),
desired_capabilities=desired_cap)
To find your Sauce Labs access key:
- Sign in to https://saucelabs.com with the username you set up when you created your account.
You will use this same username in your test script. - To find your access key:
- Click your name in the Account Profile menu in the upper-right corner.
- Click User Settings.
- Scroll down to Access Key and click Show.
- Enter the password you use to sign in to Sauce Labs to view the access key.
- Click the Copy icon.
Set Desired Capabilities
Once you have your tests set up to run in the Sauce cloud, you need to define the platform, browser, and version you want the test to run against, which is where desired capabilities come into play.
desired_cap = {
'platform': "Mac OS X 10.9",
'browserName': "chrome",
'version': "31",
You can manually enter the values you want for platform
, browsername
, and version
, or you can use the handy Platform Configurator to generate the desired_caps
values for any combination of platform, browser, and browser version.
Code Sample
This Python example script executes a simple test to open a browser, navigate to the Sauce Labs demo web app, and then close the browser. It also incorporate a number of best practices, such as using environment variables for authentication credentials. You can clone this script directly from the saucelabs-training GitHub repo and modify it as you want to test your authentication credentials, set desired capabilities, and run tests against your own web app. Y Click here to view the example script
pytest/instant-sauce-pytest4.py (source from Sauce Labs Training Python)
import pytest
import os
from selenium import webdriver
from _pytest.runner import runtestprotocol
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
@pytest.fixture
def driver(request):
sauce_username = os.environ["SAUCE_USERNAME"]
sauce_access_key = os.environ["SAUCE_ACCESS_KEY"]
remote_url = "https://ondemand.saucelabs.com:443/wd/hub"
sauceOptions = {
"screenResolution": "1280x768",
"seleniumVersion": "3.141.59",
'name': 'Example Pytest4',
"username": sauce_username,
"accessKey": sauce_access_key,
# best practices involve setting a build number for version control
"build": "build-0.0.1",
# tags to filter test reporting.
"tags": ['instant-sauce', 'ruby-rspec', 'module4'],
# setting sauce-runner specific parameters such as timeouts helps
# manage test execution speed.
"maxDuration": 1800,
"commandTimeout": 300,
"idleTimeout": 1000
}
chromeOpts = {
'platformName':"Windows 10",
'browserName': "chrome",
'browserVersion': '71.0',
'goog:chromeOptions': {'w3c': True},
'sauce:options': sauceOptions
}
browser = webdriver.Remote(remote_url, desired_capabilities=chromeOpts)
yield browser
browser.quit()
def test_should_open_chrome(driver):
driver.get("http://www.saucedemo.com")
actual_title = driver.title
expected_title = "Swag Labs"
assert expected_title == actual_title
This code sample is more complex, and relies on some libraries that you may need to install to make it work.
import os
import sys
import new
import unittest
from selenium import webdriver
from sauceclient import SauceClient
# it's best to remove the hardcoded defaults and always get these values
# from environment variables
USERNAME = os.environ['SAUCE_USERNAME']
ACCESS_KEY = os.environ['SAUCE_ACCESS_KEY']
sauce = SauceClient(USERNAME, ACCESS_KEY)
browsers = [{"platform": "Mac OS X 10.9",
"browserName": "chrome",
"version": "31"},
{"platform": "Windows 8.1",
"browserName": "internet explorer",
"version": "11"}]
def on_platforms(platforms):
def decorator(base_class):
module = sys.modules[base_class.__module__].__dict__
for i, platform in enumerate(platforms):
d = dict(base_class.__dict__)
d['desired_capabilities'] = platform
name = "%s_%s" % (base_class.__name__, i + 1)
module[name] = new.classobj(name, (base_class,), d)
return decorator
@on_platforms(browsers)
class SauceSampleTest(unittest.TestCase):
def setUp(self):
self.desired_capabilities['name'] = self.id()
sauce_url = "http://%s:%s@ondemand.saucelabs.com:80/wd/hub"
self.driver = webdriver.Remote(
desired_capabilities=self.desired_capabilities,
command_executor=sauce_url % (USERNAME, ACCESS_KEY)
)
def test_sauce(self):
self.driver.get('http://saucelabs.com/test/guinea-pig')
assert "I am a page title - Sauce Labs" in self.driver.title
comments = self.driver.find_element_by_id('comments')
comments.send_keys('Hello! I am some example comments.'
' I should be in the page after submitting the form')
self.driver.find_element_by_id('submit').click()
commented = self.driver.find_element_by_id('your_comments')
assert ('Your comments: Hello! I am some example comments.'
' I should be in the page after submitting the form'
in commented.text)
body = self.driver.find_element_by_xpath('//body')
assert 'I am some other page content' not in body.text
self.driver.find_elements_by_link_text('i am a link')[0].click()
body = self.driver.find_element_by_xpath('//body')
assert 'I am some other page content' in body.text
def tearDown(self):
print("Link to your job: https://saucelabs.com/jobs/%s" % self.driver.session_id)
try:
if sys.exc_info() == (None, None, None):
sauce.jobs.update_job(self.driver.session_id, passed=True)
else:
sauce.jobs.update_job(self.driver.session_id, passed=False)
finally:
self.driver.quit()
if __name__ == '__main__':
unittest.main()
Running Local Tests
Developing websites/apps within your local network is secure and efficient. The drawback to this method is that local assets are not publicly-accessible on the Internet, so the browsers/devices in the Sauce Labs cloud can't load and test your app. The solution is to use
Sauce Connect.
Sauce Connect is a proxy server that creates a secure tunnel connection between the Sauce Labs virtual machine that runs your test and your local network. You can also use Sauce Connect to test applications and websites that are located within your corporate firewall. Sauce Connect is not required to run tests on Sauce Labs, only in situations where the application or website you want to test is not publicly accessible. Running Tests in Parallel
Now that you’re running tests on Sauce, you may wonder how you can run your tests faster. One way to increase speed is by running tests in parallel across multiple virtual machines.
You can run your tests in parallel at two levels, and you can run your tests in parallel across multiple browsers. For example, if you have 10 tests and want to run on five browsers, this would be parallelism of five. You can also run tests across browsers and each test in parallel. Using our previous example this would be more like 50 parallel tests. Doing this requires that your tests are written in a way that they do not collide with one another, as described in our Best Practice topics avoiding external test dependencies and avoiding dependencies between tests.
For more information, check out the example scripts in our GitHub repo.
Reporting on Test Results
"Wait," you might be asking, "My test says 'Complete' but what happens if it fails?"
Unfortunately, Sauce has no way to determine whether your test passed or failed automatically, since it is determined entirely by your business logic. You can, however, tell Sauce about the results of our tests automatically using the Sauce python client and adding these lines to your test.
# this authenticates you
from sauceclient import SauceClient
sauce_client = SauceClient("YOUR_SAUCE_USERNAME", "YOUR_SAUCE_ACCESSKEY")
# this belongs in your test logic
sauce_client.jobs.update_job(driver.session_id, passed=True)
You should also follow our recommended best practice of adding build numbers, tags, and other identifying information to your tests so you can easily find and manage them in your test results and archives pages.