Back to Resources


Posted September 2, 2009

Running your Selenium tests in parallel: Python


This is the first post in our series "Running your Selenium tests in parallel", in which we're going to explain how to set up a concurrent execution environment and considerably reduce your testing times. The first client language we're going to address, as the title says, is Python. To start, let's get a set of Selenium Python tests to use: The tests are stored in a public github project. This set of tests validates our site. It checks basic structure, our login form, our signup form, and our feedback tab (UserVoice powered). The tests are grouped into Python files based on the functionality they address.

First approach: One by one execution

So,  the regular way to run these would be to run each file from the command line, like so:

$ python $ python $ python $ python

As a first approach it's not that bad; your tests will run, and you'll get decent output with the results. Execution time: 16.2 minutes 16.2 minutes isn't that bad. The problem is that once your test base starts growing, the time and effort it will take you run these tests will increase considerably. We're talking about hours in some cases. The next step to take will be to write a small script that runs them automatically, so the only thing the user will have to do is to run a single Python script that takes care of the rest:

$ python

The code in this script is:

import os import glob tests = glob.glob('test*.py') for test in tests: os.system('python %s' % test)

Easier to run, but not much faster... Execution time: 16 minutes

Second approach: A process per each test set

Let's improve this using subprocess, one of Python's multiple process libraries.

from subprocess import Popen import glob tests = glob.glob('test*.py') processes = [] for test in tests: processes.append(Popen('python %s' % test, shell=True)) for process in processes: process.wait()

Now our tests run concurrently, using a separate process per python file (4 processes total). Execution time: 8.3 minutes This is much faster! It reduces the whole execution time from the time it takes to run all the tests one after another to the time it takes the longest of the four sets of tests to end.

Note: One drawback to this method is that the output we receive isn't in any particular order. You can change that by setting the stdout parameter in the Popen instantiation and then concatenating the output in order.

The definitive solution: A process per test

We can further reduce the execution time by running all 14 individual test methods in parallel. The easiest way we've found to do that in Python is to use nose. First, install it:

$ easy_install nose==0.11 multiprocessing

Now, place yourself where your tests are, run nose and enjoy:

$ nosetests --processes=14

Much easier to run (no helper script for this), cleaner output... Execution time? 3 minutes! Do you have a better way to run your tests concurrently? Tell us about it in the comments.

Sep 2, 2009
Share this post
Copy Share Link
© 2023 Sauce Labs Inc., all rights reserved. SAUCE and SAUCE LABS are registered trademarks owned by Sauce Labs Inc. in the United States, EU, and may be registered in other jurisdictions.