Testing Your Cherrypy App
December 7th, 2008 by ScottK | No Comments | Filed in CherryPyWhen I started with CherryPy, luckily 3.1, I not only needed to learn how to work with it but also test my app as well. Others where using Nose and Twill with some success, the problem the other testing frameworks had seemed to surround the controller tests.
I discovered the testing framework within CherryPy and easily pulled it out to test my apps. There has never been a problem testing controllers, models, modules, etc. That is the what this CherryPy Example 4 is all about, testing your CherryPy app. You can find the follow along example here.
All the test case files will have to incorporate the cherrpy.test.helper class. This is in order for each of your test classes that must inherit the helper.CPWebCase class.
Controller Testing:
In the example program refer to the users_controller.py
@cherrypy.expose
def index(self, format='html', **kwargs):
if format == 'js':
cherrypy.response.headers['Content-Type'] = "application/javascript"
return "alert('format in JavaScript for index');"
elif format == "xml":
cherrypy.response.headers['Content-Type'] = "application/xml"
return "Index "
else:
return "This is the Index in HTML"
This is the index action of the controller. We need to test it to make sure that it not only responds with XML/HTML/JavaScript accordingly.
def testIndexUSersWithXML(self):
self.getPage("/users.xml", method='GET')
self.assertStatus('200 OK')
self.assertBody('Index ')
def testIndexUSersWithHTML(self):
self.getPage("/users", method='GET')
self.assertStatus('200 OK')
self.assertBody('This is the Index in HTML')
self.getPage is the call to the actively running application. assertStatus assures us that everything went ok. Of course you can also assert the other status as needed. assertBody test must match the entire response body. Generally I use assertInBody to make sure that what I’m looking for was returned rather than the whole response.
Prior to running the controller tests the controller does need to be registered with the dispatch. I’m still using the route_mapper as in CherryPy Example 3. So at the top of the controller test files I’ll include:
def setup_server():
routes = [{"name" : "user", "path" : "user", "controller" : UsersController()}]
conf = {'/': {
'request.dispatch' : rm.setup_routes(routes)
}
}
cherrypy.tree.mount(root=None, config=conf)
Then at the bottom of the file:
if __name__ == "__main__":
setup_server()
helper.testmain() //This calls for the program to run.
Outside of controllers, testing objects is pretty straight forward: assertEqual; assertNotEqual, etc. Again making sure that each test class inherits from helper.CPWebCase. test_user_model has the examples for testing a model.
As your application and test cases grows it becomes rather painful to keep running each file independently. I did this for a while with two dozen test files. Longing for a test runner I once again referred to the CherryPy module to see if they had something that would do this.
Sure enough the cherrypy.test has the method to run all your tests at once. However it required me to copy it and modify it. in the example tests folder you’ll find the test.py. This is the modified version of the cherrypy.test file.
The notable modification has to deal with the run function. Originally it contained a list of all the test cases to run at once. While this made it good as a test runner I also wanted to run singles as I was working on the model itself. So with the modification of test=None in the argument you can run the entire suite or just one test.
python test.py //Entire suite pytnon test.py test_user_model //just the test_user_model.py file
All these tests are designed to be run in the tests folder using python test.py.
Testing CherryPy apps is really easy if you incorporate the CherryPy test suite. The мебелиCherryPy Example 4 has the necessary files in the tests folder to run them.
