Index: testutil.py
===================================================================
--- testutil.py	(revision 4274)
+++ testutil.py	(working copy)
@@ -23,6 +23,8 @@
 from turbogears.identity import current_provider
 from turbogears.util import get_model
 
+from webtest import TestApp
+
 cwd = os.getcwd()
 
 # For clean tests, remove all compiled Kid templates
@@ -197,6 +199,45 @@
                 item.dropTable(ifExists=True)
 
 
+class TGWebTest(unittest.TestCase):
+    """ A WebTest enabled unit testing class.
+
+    This allows testers to subclass us and use self.app to make WebTest calls.
+    """
+    def setUp(self):
+        from cherrypy._cpwsgi import wsgiApp
+        start_cp()
+        startup.startTurboGears()
+        self.app = TestApp(wsgiApp)
+
+    def tearDown(self):
+        startup.stopTurboGears()
+        del self.app
+
+    def login_user(self, user):
+        """ Log a specified user object into the system """
+        self.app.post(config.get('identity.failure_url'), {
+                'login'     : 'Login',
+                'user_name' : user.user_name,
+                'password'  : user.password
+        })
+
+
+class DBWebTest(TGWebTest, DBTest):
+    """ A database driven WebTest enabled unit testing class.
+
+    This class will automatically setup and tear down your database, along
+    with TurboGears and WebTest before and after each unit test.
+    """
+    def setUp(self):
+        DBTest.setUp(self)
+        TGWebTest.setUp(self)
+
+    def tearDown(self):
+        TGWebTest.tearDown(self)
+        DBTest.tearDown(self)
+
+
 def reset_cp():
     cherrypy.root = None
 
@@ -305,4 +346,5 @@
 
 __all__ = ["call", "create_request", "createRequest", "DBTest",
     "attach_identity", "set_identity_user",
-    "capture_log", "print_log", "get_log", "sqlalchemy_cleanup"]
+    "capture_log", "print_log", "get_log", "sqlalchemy_cleanup",
+    "TGWebTest", "DBWebTest"]
Index: view/base.py
===================================================================
--- view/base.py	(revision 4274)
+++ view/base.py	(working copy)
@@ -126,6 +126,11 @@
         format = config.get("%s.outputformat" % enginename, "html")
     args, kw = adapt_call(engine.render, args= [],
                 kw = dict(info=info, format=format, fragment=fragment, template=template, mapping=mapping), start=1)
+
+    if hasattr(cherrypy.request, 'wsgi_environ'):
+        if 'paste.testing' in cherrypy.request.wsgi_environ:
+            cherrypy.request.wsgi_environ['paste.testing_variables']['namespace'] = info
+
     return engine.render(**kw)
 
 def transform(info, template):

