Download Install Tutorial Docs FAQ Tools WikiLicense Team IRC Planet Involvement Shop Book

root/branches/cp3-wsgi-remix/test/helper.py

Revision 1244 (checked in by dowski, 2 years ago)

Created a branch for some WSGI related ideas that I have implemented.

  • Property svn:eol-style set to native
Line 
1 """A library of helper functions for the CherryPy test suite.
2
3 The actual script that runs the entire CP test suite is called
4 "test.py" (in this folder); test.py calls this module as a library.
5
6 Usage
7 =====
8 Each individual test_*.py module imports this module (helper),
9 usually to make an instance of CPWebCase, and then call testmain().
10
11 The CP test suite script (test.py) imports this module and calls
12 run_test_suite, possibly more than once. CP applications may also
13 import test.py (to use TestHarness), which then calls helper.py.
14 """
15
16 # GREAT CARE has been taken to separate this module from test.py,
17 # because different consumers of each have mutually-exclusive import
18 # requirements. So don't go moving functions from here into test.py,
19 # or vice-versa, unless you *really* know what you're doing.
20
21 import re
22 import sys
23 import thread
24
25 import cherrypy
26 from cherrypy.lib import http, profiler
27 import webtest
28
29
30 class CPWebCase(webtest.WebCase):
31    
32     script_name = ""
33    
34     def prefix(self):
35         return self.script_name.rstrip("/")
36    
37     def exit(self):
38         sys.exit()
39    
40     def tearDown(self):
41         pass
42    
43     def getPage(self, url, headers=None, method="GET", body=None, protocol="HTTP/1.1"):
44         """Open the url. Return status, headers, body."""
45         if self.script_name:
46             url = http.urljoin(self.script_name, url)
47         webtest.WebCase.getPage(self, url, headers, method, body, protocol)
48    
49     def assertErrorPage(self, status, message=None, pattern=''):
50         """Compare the response body with a built in error page.
51         
52         The function will optionally look for the regexp pattern,
53         within the exception embedded in the error page."""
54        
55         # This will never contain a traceback
56         page = cherrypy._cperror.get_error_page(status, message=message)
57        
58         # First, test the response body without checking the traceback.
59         # Stick a match-all group (.*) in to grab the traceback.
60         esc = re.escape
61         epage = esc(page)
62         epage = epage.replace(esc('<pre id="traceback"></pre>'),
63                               esc('<pre id="traceback">') + '(.*)' + esc('</pre>'))
64         m = re.match(epage, self.body, re.DOTALL)
65         if not m:
66             self._handlewebError('Error page does not match\n' + page)
67             return
68        
69         # Now test the pattern against the traceback
70         if pattern is None:
71             # Special-case None to mean that there should be *no* traceback.
72             if m and m.group(1):
73                 self._handlewebError('Error page contains traceback')
74         else:
75             if (m is None) or (not re.search(re.escape(pattern), m.group(1))):
76                 msg = 'Error page does not contain %s in traceback'
77                 self._handlewebError(msg % repr(pattern))
78
79
80 CPTestLoader = webtest.ReloadingTestLoader()
81 CPTestRunner = webtest.TerseTestRunner(verbosity=2)
82
83 def setConfig(conf):
84     """Set the global config using a copy of conf."""
85     if isinstance(conf, basestring):
86         # assume it's a filename
87         cherrypy.config.update(conf)
88     else:
89         cherrypy.config.update(conf.copy())
90
91
92 def run_test_suite(moduleNames, server, conf):
93     """Run the given test modules using the given server and conf.
94     
95     The server is started and stopped once, regardless of the number
96     of test modules. The config, however, is reset for each module.
97     """
98     cherrypy.config.reset()
99     setConfig(conf)
100     cherrypy.server.quickstart(server)
101     cherrypy.engine.start_with_callback(_run_test_suite_thread,
102                                         args=(moduleNames, conf))
103
104 def _run_test_suite_thread(moduleNames, conf):
105     from cherrypy import _cpwsgi
106     for testmod in moduleNames:
107         # Must run each module in a separate suite,
108         # because each module uses/overwrites cherrypy globals.
109         cherrypy.tree = cherrypy._cptree.Tree()
110         cherrypy.config.reset()
111         setConfig(conf)
112        
113         m = __import__(testmod, globals(), locals())
114         setup = getattr(m, "setup_server", None)
115         if setup:
116             setup()
117        
118         for s in cherrypy.server.httpservers:
119             s.app = cherrypy.tree.dispatch
120        
121         suite = CPTestLoader.loadTestsFromName(testmod)
122         CPTestRunner.run(suite)
123        
124         teardown = getattr(m, "teardown_server", None)
125         if teardown:
126             teardown()
127     thread.interrupt_main()
128
129 def testmain(conf=None):
130     """Run __main__ as a test module, with webtest debugging."""
131     if conf is None:
132         conf = {}
133     setConfig(conf)
134     try:
135         cherrypy.server.quickstart()
136         cherrypy.engine.start_with_callback(_test_main_thread)
137     except KeyboardInterrupt:
138         cherrypy.server.stop()
139         cherrypy.engine.stop()
140
141 def _test_main_thread():
142     try:
143         webtest.WebCase.PORT = cherrypy.config.get('server.socket_port')
144         webtest.main()
145     finally:
146         thread.interrupt_main()
147
Note: See TracBrowser for help on using the browser.

Hosted by WebFaction

Log in as guest/cpguest to create tickets