Here is a sample unit test suite that allows testing of a web2py controller using the unittest module. The sample can be used as a template for writing other controller unit tests. This sample assumes the script is run from the command line and that the module is stored in the applications/myapp/tests directory where "myapp" is the name of the application being tested.
The testContactWithInvalidEmail test case will simulate a POST request to the controller method Contact with an malformed email address, and it expects the form to return an error reporting the invalid email address.
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
import os
web2py_path = '../../..'
sys.path.append(os.path.realpath(web2py_path))
os.chdir(web2py_path)
import unittest
from gluon.globals import Request, Response, Session
from gluon.shell import exec_environment
from gluon.storage import Storage
class TestDefaultController(unittest.TestCase):
def setUp(self):
self.request = Request()
self.controller = exec_environment('applications/myapp/controllers/default.py', request=self.request)
self.controller.response.view = 'unittest.html' # must specify a view. can be specified in the test method.
def testContactWithInvalidEmail(self):
self.request.env.request_method = 'POST'
self.request.vars = Storage(email='badaddress')
self.controller.contact()
form = self.controller.response._vars['form']
self.assertTrue(form.errors) # do we have errors?
self.assertTrue(form.errors.has_key('email')) # has email error?
self.assertEqual(form.errors['email'], 'invalid email!') # do we have an invalid email error?
if __name__ == '__main__':
unittest.main()
#!/usr/bin/python
# -*- coding: utf-8 -*-
def index():
return response.render(dict())
def contact():
form = FORM(
INPUT(_type='text', _name='email',requires=IS_EMAIL())
)
# Call form.accepts to setup form.vars.
isOk = form.accepts(request.vars, formname=None)
# Check if form input is validate only on a postback.
if request.env.request_method == 'POST':
if isOk:
# send email or do something
response.flash = 'Your message has been sent. Thank you.'
elif form.errors:
response.flash = 'The request contains one or more errors. All fields are required.'
else:
response.flash = None
return response.render(dict(form=form))
{{=response._vars}}