Acceptance testing a CherryPy application with Robot Framework

I recently received the Python Testing Cookbook authored by Greg L. Turnquist and was happy to read about recipes on acceptance testing using Robot Framework. We’ve been using this tool at work for a few weeks now with great results. Greg shows how to test a web application using the Selenium Library extension for Robot Framework and I thought it’d be fun to demonstrate how to test a CherryPy application following his recipe. So here we go.

First some requirements:

$ mkvirtualenv --distribute --no-site-packages --unzip-setuptools acceptance
(acceptance)$ pip install cherrypy
(acceptance)$ pip install robotframework
(acceptance)$ pip install robotframework-seleniumlibrary

Let’s define a simple CherryPy application, which displays a input text where to type a message. When the submit button is pressed, the message is sent to the server and returned as-is. Well it’s an echo message really.

import cherrypy
__all__ = ['Echo']
class Echo(object):
    def index(self):
        return """<html>
<head><title>Robot Framework Test for CherryPy</title></head>
<form method="post" action="/echo">
<input type="text" name="message" />
<input type="submit" />
    def echo(self, message):
        return message
if __name__ == '__main__':

Save the code above in a module named

Next, we create an extension to Robot Framework that will manage CherryPy. Save the following in a module It’s important to respect that name since Robot Framework expects the module and its class to match in names.

import imp
import os, os.path
import cherrypy
class CherryPyLib(object):
    def setup_cherrypy(self, conf_file=None):
        Configures the CherryPy engine and server using
        the built-in 'embedded' environment mode.
        If provided, `conf_file` is a path to a CherryPy
        configuration file used in addition.
        cherrypy.config.update({"environment": "embedded"})
        if conf_file:
    def start_cherrypy(self):
        Starts a CherryPy engine.
    def exit_cherrypy(self):
        Terminates a CherryPy engine.
    def mount_application(self, appmod, appcls, directory=None):
        Mounts an application to be tested. `appmod` is the name
        of a Python module containing `appcls`. The module is
        looked for in the given directory. If not provided, we use
        the current one instead.
        directory = directory or os.getcwd()
        file, filename, description = imp.find_module(appmod, [directory])
        mod = imp.load_module(appmod, file, filename, description)
        if hasattr(mod, appcls):
            cls = getattr(mod, appcls)
            app = cls()
            raise ImportError, "cannot import name %s from %s" % (appcls, appmod)

Note that we start and stop the CherryPy server during the test itself, meaning you don’t need to start it separately. Pure awesomeness.

Finally let’s write a straightforward acceptance test to validate the overall workflow of echoing a message using our little application.

Library	SeleniumLibrary
Library	CherryPyLib
Suite Setup	Start Dependencies
Suite Teardown	Shutdown Dependencies
Test Setup	Mount Application	myapp	Echo

${MSG}	Hello World
${HOST}	http://localhost:8080/

***Test Cases***
Echo ${MSG}
     Open Browser	${HOST}
     Input text		message		${MSG}
     Submit form
     Page Should Contain		${MSG}
     Close All Browsers

Start Dependencies
    Setup Cherrypy
    Start CherryPy
    Start Selenium Server
    Sleep 	3s

Shutdown Dependencies
    Stop Selenium Server
    Exit CherryPy

Save the test above into a file named testmyapp.txt. You can finally run the test as follow:

(acceptance)$ pybot --pythonpath . testmyapp.txt

This will start CherryPy, Selenium’s proxy server and Firefox within which the test case will be run. Easy, elegant and powerful.


  1. anler
      June 22, 2011

    Hi, when I run the case with pybot the program stays waiting for some input (I think) but I don’t know how to do it go further.
    Thanks for the tut!

  2. Sylvain Hellegouarch
      June 23, 2011

    Hey Anler,

    It’s difficult to tell why it’s hanging. You may want to enable the logging through cherrypy.config.update so that it shows you what might be going on in CherryPy. Assuming it’s where the problem lies.

    Otherwise, could well be a difference in one of your package version (Python, CherryPy, RobotFramework).

  3. Ryan
      September 10, 2011

    Great post! I was looking something like this for testing my CherryPy apps.

    A hint for those who try the example: it seems Robot Framework is “fickle” (precise is probably a better word) in the spacing the test file (“testmyapp.txt”) above. If you have issues, try replacing spaces in the variables with tabs till works.

  4. Greg Turnquist
      October 25, 2011


    It may be hard to notice, but Robot Framework needs at least two spaces to “see” a break from one cell to the next. Tabs are also viable.

    This was a keen issue I had to overcome in typesetting my book, and I tried to include enough extra notes so the reader didn’t get lost in that.