As per http://webpy.org/cookbook/testing_with_paste_and_nose I've been
working with TestApp to test my web.py application. However, there's a
problem with the way web.py handles errors, demonstrated by the
following trivial script:
------------------------------------------------------------------------------
import unittest
from web import application
from paste.fixture import TestApp
urls = ("/", "thing")
app = application(urls, globals())
class thing:
def GET(self):
raise Exception("something went wrong")
class TestWebUI(unittest.TestCase):
def setUp(self):
middleware = []
self.client = TestApp(app.wsgifunc(*middleware))
def test_index(self):
r = self.client.get('/')
if __name__ == "__main__":
unittest.main()
------------------------------------------------------------------------------
TestApp doesn't like it if anything is printed to the error stream
(according to Ian Bicking, who would know :)). You get an exception
that looks like this:
------------------------------------------------------------------------------
$ python ~/Scratch/demo_webpy_traceback_problem.py
F
======================================================================
FAIL: test_index (__main__.TestWebUI)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/aquarius/Scratch/demo_webpy_traceback_problem.py", line
17, in test_index
r = self.client.get('/')
File "/usr/lib/pymodules/python2.6/paste/fixture.py", line 208, in
get
return self.do_request(req, status=status)
File "/usr/lib/pymodules/python2.6/paste/fixture.py", line 389, in
do_request
**req.environ)
File "/usr/lib/pymodules/python2.6/paste/wsgilib.py", line 343, in
raw_interactive
app_iter = application(basic_environ, start_response)
File "/usr/lib/pymodules/python2.6/paste/lint.py", line 170, in
lint_app
iterator = application(environ, start_response_wrapper)
File "/home/aquarius/Programs/Mine/myapp/trunk/lib/web/
application.py", line 282, in wsgi
result = self.handle_with_processors()
File "/home/aquarius/Programs/Mine/myapp/trunk/lib/web/
application.py", line 252, in handle_with_processors
return process(self.processors)
File "/home/aquarius/Programs/Mine/myapp/trunk/lib/web/
application.py", line 248, in process
print >> web.debug, traceback.format_exc()
File "/home/aquarius/Programs/Mine/myapp/trunk/lib/web/webapi.py",
line 339, in _debugwrite
out.write(x)
File "/usr/lib/pymodules/python2.6/paste/lint.py", line 221, in
write
self.errors.write(s)
File "/usr/lib/pymodules/python2.6/paste/wsgilib.py", line 375, in
write
"No errors should be written (got: %r)" % value)
AssertionError: No errors should be written (got: 'Traceback (most
recent call last):\n File "/home/aquarius/Programs/Mine/myapp/trunk/
lib/web/application.py", line 240, in process\n return p(lambda:
process(processors))\n File "/home/aquarius/Programs/Mine/myapp/trunk/
lib/web/application.py", line 561, in processor\n return handler()
\n File "/home/aquarius/Programs/Mine/myapp/trunk/lib/web/
application.py", line 240, in <lambda>\n return p(lambda:
process(processors))\n File "/home/aquarius/Programs/Mine/myapp/trunk/
lib/web/application.py", line 248, in process\n print >> web.debug,
traceback.format_exc()\n File "/home/aquarius/Programs/Mine/myapp/
trunk/lib/web/webapi.py", line 339, in _debugwrite\n out.write(x)
\n File "/usr/lib/pymodules/python2.6/paste/lint.py", line 221, in
write\n self.errors.write(s)\n File "/usr/lib/pymodules/python2.6/
paste/wsgilib.py", line 375, in write\n "No errors should be
written (got: %r)" % value)\nAssertionError: No errors should be
written (got: \'Traceback (most recent call last):\\n File "/home/
aquarius/Programs/Mine/myapp/trunk/lib/web/application.py", line 240,
in process\\n return p(lambda: process(processors))\\n File "/home/
aquarius/Programs/Mine/myapp/trunk/lib/web/application.py", line 576,
in processor\\n result = handler()\\n File "/home/aquarius/
Programs/Mine/myapp/trunk/lib/web/application.py", line 240, in
<lambda>\\n return p(lambda: process(processors))\\n File "/home/
aquarius/Programs/Mine/myapp/trunk/lib/web/application.py", line 248,
in process\\n print >> web.debug, traceback.format_exc()\\n File "/
home/aquarius/Programs/Mine/myapp/trunk/lib/web/webapi.py", line 339,
in _debugwrite\\n out.write(x)\\n File "/usr/lib/pymodules/
python2.6/paste/lint.py", line 221, in write\\n self.errors.write(s)
\\n File "/usr/lib/pymodules/python2.6/paste/wsgilib.py", line 375,
in write\\n "No errors should be written (got: %r)" % value)\
\nAssertionError: No errors should be written (got: \\\'Traceback
(most recent call last):\\\\n File "/home/aquarius/Programs/Mine/
myapp/trunk/lib/web/application.py", line 240, in process\\\\n
return p(lambda: process(processors))\\\\n File "/home/aquarius/
Programs/Mine/myapp/trunk/lib/web/application.py", line 561, in
processor\\\\n return handler()\\\\n File "/home/aquarius/Programs/
Mine/myapp/trunk/lib/web/application.py", line 240, in <lambda>\\\
\n return p(lambda: process(processors))\\\\n File "/home/aquarius/
Programs/Mine/myapp/trunk/lib/web/application.py", line 248, in process
\\\\n print >> web.debug, traceback.format_exc()\\\\n File "/home/
aquarius/Programs/Mine/myapp/trunk/lib/web/webapi.py", line 339, in
_debugwrite\\\\n out.write(x)\\\\n File "/usr/lib/pymodules/
python2.6/paste/lint.py", line 221, in write\\\\n
self.errors.write(s)\\\\n File "/usr/lib/pymodules/python2.6/paste/
wsgilib.py", line 375, in write\\\\n "No errors should be written
(got: %r)" % value)\\\\nAssertionError: No errors should be written
(got: \\\\\\\'Traceback (most recent call last):\\\\\\\\n File "/home/
aquarius/Programs/Mine/myapp/trunk/lib/web/application.py", line 240,
in process\\\\\\\\n return p(lambda: process(processors))\\\\\\\\n
File "/home/aquarius/Programs/Mine/myapp/trunk/lib/web/
application.py", line 561, in processor\\\\\\\\n return handler()\\\
\\\\\n File "/home/aquarius/Programs/Mine/myapp/trunk/lib/web/
application.py", line 240, in <lambda>\\\\\\\\n return p(lambda:
process(processors))\\\\\\\\n File "/home/aquarius/Programs/Mine/
myapp/trunk/lib/web/application.py", line 248, in process\\\\\\\\n
print >> web.debug, traceback.format_exc()\\\\\\\\n File "/home/
aquarius/Programs/Mine/myapp/trunk/lib/web/webapi.py", line 339, in
_debugwrite\\\\\\\\n out.write(x)\\\\\\\\n File "/usr/lib/
pymodules/python2.6/paste/lint.py", line 221, in write\\\\\\\\n
self.errors.write(s)\\\\\\\\n File "/usr/lib/pymodules/python2.6/
paste/wsgilib.py", line 375, in write\\\\\\\\n "No errors should be
written (got: %r)" % value)\\\\\\\\nAssertionError: No errors should
be written (got: \\\\\\\\\\\\\\\'Traceback (most recent call last):\\\\
\\\\\\\\\\\\n File "/home/aquarius/Programs/Mine/myapp/trunk/lib/web/
application.py", line 242, in process\\\\\\\\\\\\\\\\n return
self.handle()\\\\\\\\\\\\\\\\n File "/home/aquarius/Programs/Mine/
myapp/trunk/lib/web/application.py", line 233, in handle\\\\\\\\\\\\\\\
\n return self._delegate(fn, self.fvars, args)\\\\\\\\\\\\\\\\n
File "/home/aquarius/Programs/Mine/myapp/trunk/lib/web/
application.py", line 415, in _delegate\\\\\\\\\\\\\\\\n return
handle_class(cls)\\\\\\\\\\\\\\\\n File "/home/aquarius/Programs/Mine/
myapp/trunk/lib/web/application.py", line 390, in handle_class\\\\\\\\\
\\\\\\\n return tocall(*args)\\\\\\\\\\\\\\\\n File "/home/
aquarius/Scratch/demo_webpy_traceback_problem.py", line 9, in GET\\\\\\
\\\\\\\\\\n raise Exception("something went wrong")\\\\\\\\\\\\\\\
\nException: something went wrong\\\\\\\\\\\\\\\\n\\\\\\\\\\\\\\\')\\\\
\\\\n\\\\\\\')\\\\n\\\')\\n\')\n')
----------------------------------------------------------------------
Ran 1 test in 0.015s
FAILED (failures=1)
------------------------------------------------------------------------------
which is obviously horrid. paste.fixture sets a value in the
environment so you can know whether to handle errors yourself or pass
them up to the paste testing infrastructure. The below patch against
git HEAD implements a check for this, so that any errors caused don't
make paste mangle the exceptions.
------------------------------------------------------------------------------
diff --git a/web/application.py b/web/application.py
index 4104fe7..d1d3af4 100755
--- a/web/application.py
+++ b/web/application.py
@@ -245,8 +245,11 @@ class application:
except (KeyboardInterrupt, SystemExit):
raise
except:
- print >> web.debug, traceback.format_exc()
- raise self.internalerror()
+ if web.ctx.env.get("paste.throw_errors", False):
+ raise
+ else:
+ print >> web.debug, traceback.format_exc()
+ raise self.internalerror()
# processors must be applied in the resvere order. (??)
return process(self.processors)
------------------------------------------------------------------------------
Cheers,
sil
--
You received this message because you are subscribed to the Google Groups
"web.py" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/webpy?hl=en.