Automate Your Acceptance Tests With Python

Recently I’ve been cooking up some new acceptance-level tests for Pulse. The sort of tests that need to take a Pulse release package, unpack it, start the server and poke it with a stick. This is the sort of automation that I would typically use bash for: since a lot of the work involves executing and managing subprocess. However, I had learned from earlier testing that process control from bash is not very portable. More specifically, the behaviour of Cygwin bash on Windows differs considerably from *nix bash. At the time, I worked around the problem by doing some process control using Ant, but there had to be a better way.

Enter Python. Or, more specifically, the new(ish) subprocess module (introduced in Python 2.4). With this module Python finally has a concise but powerful way to launch and control subprocesses. It also includes convenient ways to handle subprocess I/O, including setting up pipelines. What’s more, I have so far found it to be quite portable between Linux and Windows.

Starting with something simple, let’s say you just want to launch a command synchronously (much as you would in a shell script):

exitcode = subprocess.call([“cat”, “foo.txt”])

Simple. Want to set up a pipeline like `dmesg | grep hda` (capturing the final output)? Here’s an example straight from the doco:

from subprocess import Popen

p1 = Popen([“dmesg”], stdout=PIPE)
p2 = Popen([“grep”, “hda”], stdin=p1.stdout, stdout=PIPE)
output = p2.communicate()[0]

For my specific case, I used the ability to launch a Pulse server processes in the background and capture the output extensively. When done, I shut down the server using the standard shutdown script (testing of said script being a nice side-effect). An asynchronous child is started simply by creating a Popen object:

from subprocess import *

# Launch process, capturing output
out = open(“stdout.txt”, “w”)
err = open(“stderr.txt”, “w”)
server = Popen([“startup.sh”], stdout=out, stderr=err)

# Do some stuff with the process…

# Trigger a shutdown and wait for the process to exit
call([“shutdown.sh”])
exitcode = server.wait()

I have simplified this example a bit, but the real work is all there, and it’s pleasantly straightforward. This combined well with Python’s simple XML-RPC API, which I used to manipulate the running server.

So far the switch to from bash/Ant to Python has been a great success. If you need a cross-platform way to automate your acceptance testing, give it a go.

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • del.icio.us
  • digg
  • DZone
  • Ma.gnolia
  • Reddit
  • Simpy
  • Slashdot
  • StumbleUpon
  • Technorati

Leave a Reply