[unittest2] update to unittest2 assertRaises api stable
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Mon, 10 Jan 2011 12:28:09 +0100
branchstable
changeset 6796 e70ca9abfc51
parent 6795 f29d24c3d687
child 6797 90d687bd4c52
[unittest2] update to unittest2 assertRaises api
entities/test/unittest_wfobjs.py
hooks/test/unittest_hooks.py
server/test/unittest_hook.py
server/test/unittest_migractions.py
server/test/unittest_msplanner.py
server/test/unittest_repository.py
server/test/unittest_storage.py
server/test/unittest_undo.py
test/unittest_schema.py
web/test/unittest_application.py
web/test/unittest_views_basecontrollers.py
--- a/entities/test/unittest_wfobjs.py	Fri Jan 07 18:51:50 2011 +0100
+++ b/entities/test/unittest_wfobjs.py	Mon Jan 10 12:28:09 2011 +0100
@@ -15,7 +15,9 @@
 #
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
+
 from __future__ import with_statement
+
 from cubicweb.devtools.testlib import CubicWebTC
 from cubicweb import ValidationError
 from cubicweb.server.session import security_enabled
@@ -55,8 +57,9 @@
         wf.add_state(u'foo', initial=True)
         self.commit()
         wf.add_state(u'foo')
-        ex = self.assertRaises(ValidationError, self.commit)
-        self.assertEqual(ex.errors, {'name-subject': 'workflow already have a state of that name'})
+        with self.assertRaises(ValidationError) as cm:
+            self.commit()
+        self.assertEqual(cm.exception.errors, {'name-subject': 'workflow already have a state of that name'})
         # no pb if not in the same workflow
         wf2 = add_wf(self, 'Company')
         foo = wf2.add_state(u'foo', initial=True)
@@ -65,8 +68,9 @@
         bar = wf.add_state(u'bar')
         self.commit()
         bar.set_attributes(name=u'foo')
-        ex = self.assertRaises(ValidationError, self.commit)
-        self.assertEqual(ex.errors, {'name-subject': 'workflow already have a state of that name'})
+        with self.assertRaises(ValidationError) as cm:
+            self.commit()
+        self.assertEqual(cm.exception.errors, {'name-subject': 'workflow already have a state of that name'})
 
     def test_duplicated_transition(self):
         wf = add_wf(self, 'Company')
@@ -74,8 +78,9 @@
         bar = wf.add_state(u'bar')
         wf.add_transition(u'baz', (foo,), bar, ('managers',))
         wf.add_transition(u'baz', (bar,), foo)
-        ex = self.assertRaises(ValidationError, self.commit)
-        self.assertEqual(ex.errors, {'name-subject': 'workflow already have a transition of that name'})
+        with self.assertRaises(ValidationError) as cm:
+            self.commit()
+        self.assertEqual(cm.exception.errors, {'name-subject': 'workflow already have a transition of that name'})
         # no pb if not in the same workflow
         wf2 = add_wf(self, 'Company')
         foo = wf.add_state(u'foo', initial=True)
@@ -86,8 +91,9 @@
         biz = wf.add_transition(u'biz', (bar,), foo)
         self.commit()
         biz.set_attributes(name=u'baz')
-        ex = self.assertRaises(ValidationError, self.commit)
-        self.assertEqual(ex.errors, {'name-subject': 'workflow already have a transition of that name'})
+        with self.assertRaises(ValidationError) as cm:
+            self.commit()
+        self.assertEqual(cm.exception.errors, {'name-subject': 'workflow already have a transition of that name'})
 
 
 class WorkflowTC(CubicWebTC):
@@ -150,10 +156,10 @@
         s = wf.add_state(u'foo', initial=True)
         self.commit()
         with security_enabled(self.session, write=False):
-            ex = self.assertRaises(ValidationError, self.session.execute,
-                               'SET X in_state S WHERE X eid %(x)s, S eid %(s)s',
-                               {'x': self.user().eid, 's': s.eid})
-            self.assertEqual(ex.errors, {'in_state-subject': "state doesn't belong to entity's workflow. "
+            with self.assertRaises(ValidationError) as cm:
+                self.session.execute('SET X in_state S WHERE X eid %(x)s, S eid %(s)s',
+                                     {'x': self.user().eid, 's': s.eid})
+            self.assertEqual(cm.exception.errors, {'in_state-subject': "state doesn't belong to entity's workflow. "
                                       "You may want to set a custom workflow for this entity first."})
 
     def test_fire_transition(self):
@@ -197,18 +203,18 @@
         cnx = self.login('tutu')
         req = self.request()
         iworkflowable = req.entity_from_eid(self.member.eid).cw_adapt_to('IWorkflowable')
-        ex = self.assertRaises(ValidationError,
-                               iworkflowable.fire_transition, 'deactivate')
-        self.assertEqual(ex.errors, {'by_transition-subject': "transition may not be fired"})
+        with self.assertRaises(ValidationError) as cm:
+            iworkflowable.fire_transition('deactivate')
+        self.assertEqual(cm.exception.errors, {'by_transition-subject': "transition may not be fired"})
         cnx.close()
         cnx = self.login('member')
         req = self.request()
         iworkflowable = req.entity_from_eid(self.member.eid).cw_adapt_to('IWorkflowable')
         iworkflowable.fire_transition('deactivate')
         cnx.commit()
-        ex = self.assertRaises(ValidationError,
-                               iworkflowable.fire_transition, 'activate')
-        self.assertEqual(ex.errors, {'by_transition-subject': "transition may not be fired"})
+        with self.assertRaises(ValidationError) as cm:
+            iworkflowable.fire_transition('activate')
+        self.assertEqual(cm.exception.errors, {'by_transition-subject': "transition may not be fired"})
 
     def test_fire_transition_owned_by(self):
         self.execute('INSERT RQLExpression X: X exprtype "ERQLExpression", '
@@ -280,9 +286,9 @@
         self.assertEqual(iworkflowable.subworkflow_input_transition(), None)
         # force back to swfstate1 is impossible since we can't any more find
         # subworkflow input transition
-        ex = self.assertRaises(ValidationError,
-                               iworkflowable.change_state, swfstate1, u'gadget')
-        self.assertEqual(ex.errors, {'to_state-subject': "state doesn't belong to entity's workflow"})
+        with self.assertRaises(ValidationError) as cm:
+            iworkflowable.change_state(swfstate1, u'gadget')
+        self.assertEqual(cm.exception.errors, {'to_state-subject': "state doesn't belong to entity's workflow"})
         self.rollback()
         # force back to state1
         iworkflowable.change_state('state1', u'gadget')
@@ -317,8 +323,9 @@
         state3 = mwf.add_state(u'state3')
         mwf.add_wftransition(u'swftr1', swf, state1,
                              [(swfstate2, state2), (swfstate2, state3)])
-        ex = self.assertRaises(ValidationError, self.commit)
-        self.assertEqual(ex.errors, {'subworkflow_exit-subject': u"can't have multiple exits on the same state"})
+        with self.assertRaises(ValidationError) as cm:
+            self.commit()
+        self.assertEqual(cm.exception.errors, {'subworkflow_exit-subject': u"can't have multiple exits on the same state"})
 
     def test_swf_fire_in_a_row(self):
         # sub-workflow
@@ -435,8 +442,9 @@
         wf.add_state('asleep')
         self.execute('SET X custom_workflow WF WHERE X eid %(x)s, WF eid %(wf)s',
                      {'wf': wf.eid, 'x': self.member.eid})
-        ex = self.assertRaises(ValidationError, self.commit)
-        self.assertEqual(ex.errors, {'custom_workflow-subject': u'workflow has no initial state'})
+        with self.assertRaises(ValidationError) as cm:
+            self.commit()
+        self.assertEqual(cm.exception.errors, {'custom_workflow-subject': u'workflow has no initial state'})
 
     def test_custom_wf_bad_etype(self):
         """try to set a custom workflow which doesn't apply to entity type"""
@@ -444,8 +452,9 @@
         wf.add_state('asleep', initial=True)
         self.execute('SET X custom_workflow WF WHERE X eid %(x)s, WF eid %(wf)s',
                      {'wf': wf.eid, 'x': self.member.eid})
-        ex = self.assertRaises(ValidationError, self.commit)
-        self.assertEqual(ex.errors, {'custom_workflow-subject': u"workflow isn't a workflow for this type"})
+        with self.assertRaises(ValidationError) as cm:
+            self.commit()
+        self.assertEqual(cm.exception.errors, {'custom_workflow-subject': u"workflow isn't a workflow for this type"})
 
     def test_del_custom_wf(self):
         """member in some state shared by the new workflow, nothing has to be
@@ -590,9 +599,9 @@
         cnx = self.login('stduser')
         user = cnx.user(self.session)
         iworkflowable = user.cw_adapt_to('IWorkflowable')
-        ex = self.assertRaises(ValidationError,
-                               iworkflowable.fire_transition, 'activate')
-        self.assertEqual(self._cleanup_msg(ex.errors['by_transition-subject']),
+        with self.assertRaises(ValidationError) as cm:
+            iworkflowable.fire_transition('activate')
+        self.assertEqual(self._cleanup_msg(cm.exception.errors['by_transition-subject']),
                           u"transition isn't allowed from")
         cnx.close()
 
@@ -600,9 +609,9 @@
         cnx = self.login('stduser')
         user = cnx.user(self.session)
         iworkflowable = user.cw_adapt_to('IWorkflowable')
-        ex = self.assertRaises(ValidationError,
-                               iworkflowable.fire_transition, 'dummy')
-        self.assertEqual(self._cleanup_msg(ex.errors['by_transition-subject']),
+        with self.assertRaises(ValidationError) as cm:
+            iworkflowable.fire_transition('dummy')
+        self.assertEqual(self._cleanup_msg(cm.exception.errors['by_transition-subject']),
                           u"transition isn't allowed from")
         cnx.close()
 
@@ -614,9 +623,9 @@
         iworkflowable.fire_transition('deactivate')
         cnx.commit()
         session.set_pool()
-        ex = self.assertRaises(ValidationError,
-                               iworkflowable.fire_transition, 'deactivate')
-        self.assertEqual(self._cleanup_msg(ex.errors['by_transition-subject']),
+        with self.assertRaises(ValidationError) as cm:
+            iworkflowable.fire_transition('deactivate')
+        self.assertEqual(self._cleanup_msg(cm.exception.errors['by_transition-subject']),
                                             u"transition isn't allowed from")
         cnx.rollback()
         session.set_pool()
--- a/hooks/test/unittest_hooks.py	Fri Jan 07 18:51:50 2011 +0100
+++ b/hooks/test/unittest_hooks.py	Mon Jan 10 12:28:09 2011 +0100
@@ -115,8 +115,9 @@
 
     def test_unsatisfied_constraints(self):
         releid = self.execute('SET U in_group G WHERE G name "owners", U login "admin"')[0][0]
-        ex = self.assertRaises(ValidationError, self.commit)
-        self.assertEqual(ex.errors,
+        with self.assertRaises(ValidationError) as cm:
+            self.commit()
+        self.assertEqual(cm.exception.errors,
                           {'in_group-object': u'RQLConstraint NOT O name "owners" failed'})
 
     def test_html_tidy_hook(self):
@@ -227,25 +228,25 @@
 class CWPropertyHooksTC(CubicWebTC):
 
     def test_unexistant_eproperty(self):
-        ex = self.assertRaises(ValidationError,
-                          self.execute, 'INSERT CWProperty X: X pkey "bla.bla", X value "hop", X for_user U')
-        self.assertEqual(ex.errors, {'pkey-subject': 'unknown property key bla.bla'})
-        ex = self.assertRaises(ValidationError,
-                          self.execute, 'INSERT CWProperty X: X pkey "bla.bla", X value "hop"')
-        self.assertEqual(ex.errors, {'pkey-subject': 'unknown property key bla.bla'})
+        with self.assertRaises(ValidationError) as cm:
+            self.execute('INSERT CWProperty X: X pkey "bla.bla", X value "hop", X for_user U')
+        self.assertEqual(cm.exception.errors, {'pkey-subject': 'unknown property key bla.bla'})
+        with self.assertRaises(ValidationError) as cm:
+            self.execute('INSERT CWProperty X: X pkey "bla.bla", X value "hop"')
+        self.assertEqual(cm.exception.errors, {'pkey-subject': 'unknown property key bla.bla'})
 
     def test_site_wide_eproperty(self):
-        ex = self.assertRaises(ValidationError,
-                               self.execute, 'INSERT CWProperty X: X pkey "ui.site-title", X value "hop", X for_user U')
-        self.assertEqual(ex.errors, {'for_user-subject': "site-wide property can't be set for user"})
+        with self.assertRaises(ValidationError) as cm:
+            self.execute('INSERT CWProperty X: X pkey "ui.site-title", X value "hop", X for_user U')
+        self.assertEqual(cm.exception.errors, {'for_user-subject': "site-wide property can't be set for user"})
 
     def test_bad_type_eproperty(self):
-        ex = self.assertRaises(ValidationError,
-                               self.execute, 'INSERT CWProperty X: X pkey "ui.language", X value "hop", X for_user U')
-        self.assertEqual(ex.errors, {'value-subject': u'unauthorized value'})
-        ex = self.assertRaises(ValidationError,
-                          self.execute, 'INSERT CWProperty X: X pkey "ui.language", X value "hop"')
-        self.assertEqual(ex.errors, {'value-subject': u'unauthorized value'})
+        with self.assertRaises(ValidationError) as cm:
+            self.execute('INSERT CWProperty X: X pkey "ui.language", X value "hop", X for_user U')
+        self.assertEqual(cm.exception.errors, {'value-subject': u'unauthorized value'})
+        with self.assertRaises(ValidationError) as cm:
+            self.execute('INSERT CWProperty X: X pkey "ui.language", X value "hop"')
+        self.assertEqual(cm.exception.errors, {'value-subject': u'unauthorized value'})
 
 
 class SchemaHooksTC(CubicWebTC):
--- a/server/test/unittest_hook.py	Fri Jan 07 18:51:50 2011 +0100
+++ b/server/test/unittest_hook.py	Mon Jan 10 12:28:09 2011 +0100
@@ -18,6 +18,8 @@
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """unit/functional tests for cubicweb.server.hook"""
 
+from __future__ import with_statement
+
 from logilab.common.testlib import TestCase, unittest_main, mock_object
 
 
@@ -101,20 +103,23 @@
     def test_register_bad_hook1(self):
         class _Hook(hook.Hook):
             events = ('before_add_entiti',)
-        ex = self.assertRaises(Exception, self.o.register, _Hook)
-        self.assertEqual(str(ex), 'bad event before_add_entiti on %s._Hook' % __name__)
+        with self.assertRaises(Exception) as cm:
+            self.o.register(_Hook)
+        self.assertEqual(str(cm.exception), 'bad event before_add_entiti on %s._Hook' % __name__)
 
     def test_register_bad_hook2(self):
         class _Hook(hook.Hook):
             events = None
-        ex = self.assertRaises(Exception, self.o.register, _Hook)
-        self.assertEqual(str(ex), 'bad .events attribute None on %s._Hook' % __name__)
+        with self.assertRaises(Exception) as cm:
+            self.o.register(_Hook)
+        self.assertEqual(str(cm.exception), 'bad .events attribute None on %s._Hook' % __name__)
 
     def test_register_bad_hook3(self):
         class _Hook(hook.Hook):
             events = 'before_add_entity'
-        ex = self.assertRaises(Exception, self.o.register, _Hook)
-        self.assertEqual(str(ex), 'bad event b on %s._Hook' % __name__)
+        with self.assertRaises(Exception) as cm:
+            self.o.register(_Hook)
+        self.assertEqual(str(cm.exception), 'bad event b on %s._Hook' % __name__)
 
     def test_call_hook(self):
         self.o.register(AddAnyHook)
--- a/server/test/unittest_migractions.py	Fri Jan 07 18:51:50 2011 +0100
+++ b/server/test/unittest_migractions.py	Mon Jan 10 12:28:09 2011 +0100
@@ -552,8 +552,9 @@
             self.commit()
 
     def test_remove_dep_cube(self):
-        ex = self.assertRaises(ConfigurationError, self.mh.cmd_remove_cube, 'file')
-        self.assertEqual(str(ex), "can't remove cube file, used as a dependency")
+        with self.assertRaises(ConfigurationError) as cm:
+            self.mh.cmd_remove_cube('file')
+        self.assertEqual(str(cm.exception), "can't remove cube file, used as a dependency")
 
     def test_introduce_base_class(self):
         self.mh.cmd_add_entity_type('Para')
--- a/server/test/unittest_msplanner.py	Fri Jan 07 18:51:50 2011 +0100
+++ b/server/test/unittest_msplanner.py	Mon Jan 10 12:28:09 2011 +0100
@@ -15,6 +15,9 @@
 #
 # You should have received a copy of the GNU Lesser General Public License along
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
+"""unit tests for module cubicweb.server.msplanner"""
+
+from __future__ import with_statement
 
 from logilab.common.decorators import clear_cache
 
@@ -2013,15 +2016,15 @@
 
     def test_source_conflict_1(self):
         self.repo._type_source_cache[999999] = ('Note', 'cards', 999999)
-        ex = self.assertRaises(BadRQLQuery,
-                               self._test, 'Any X WHERE X cw_source S, S name "system", X eid %(x)s',
-                               [], {'x': 999999})
-        self.assertEqual(str(ex), 'source conflict for term %(x)s')
+        with self.assertRaises(BadRQLQuery) as cm:
+            self._test('Any X WHERE X cw_source S, S name "system", X eid %(x)s',
+                       [], {'x': 999999})
+        self.assertEqual(str(cm.exception), 'source conflict for term %(x)s')
 
     def test_source_conflict_2(self):
-        ex = self.assertRaises(BadRQLQuery,
-                               self._test, 'Card X WHERE X cw_source S, S name "systeme"', [])
-        self.assertEqual(str(ex), 'source conflict for term X')
+        with self.assertRaises(BadRQLQuery) as cm:
+            self._test('Card X WHERE X cw_source S, S name "systeme"', [])
+        self.assertEqual(str(cm.exception), 'source conflict for term X')
 
     def test_source_conflict_3(self):
         self.skipTest('oops')
--- a/server/test/unittest_repository.py	Fri Jan 07 18:51:50 2011 +0100
+++ b/server/test/unittest_repository.py	Mon Jan 10 12:28:09 2011 +0100
@@ -154,8 +154,9 @@
             self.assertRaises(ValidationError,
                               self.execute, 'SET X name "toto" WHERE X is CWGroup, X name "guests"')
             self.failUnless(self.execute('Any X WHERE X is CWGroup, X name "toto"'))
-            ex = self.assertRaises(QueryError, self.commit)
-            self.assertEqual(str(ex), 'transaction must be rollbacked')
+            with self.assertRaises(QueryError) as cm:
+                self.commit()
+            self.assertEqual(str(cm.exception), 'transaction must be rollbacked')
             self.rollback()
             self.failIf(self.execute('Any X WHERE X is CWGroup, X name "toto"'))
 
@@ -170,8 +171,9 @@
             self.assertRaises(Unauthorized,
                               self.execute, 'SET X name "toto" WHERE X is CWGroup, X name "guests"')
             self.failUnless(self.execute('Any X WHERE X is CWGroup, X name "toto"'))
-            ex = self.assertRaises(QueryError, self.commit)
-            self.assertEqual(str(ex), 'transaction must be rollbacked')
+            with self.assertRaises(QueryError) as cm:
+                self.commit()
+            self.assertEqual(str(cm.exception), 'transaction must be rollbacked')
             self.rollback()
             self.failIf(self.execute('Any X WHERE X is CWGroup, X name "toto"'))
 
@@ -276,8 +278,9 @@
             repo.execute(cnxid, 'DELETE CWUser X WHERE X login "toto"')
             repo.commit(cnxid)
         try:
-            ex = self.assertRaises(Exception, run_transaction)
-            self.assertEqual(str(ex), 'try to access pool on a closed session')
+            with self.assertRaises(Exception) as cm:
+                run_transaction()
+            self.assertEqual(str(cm.exception), 'try to access pool on a closed session')
         finally:
             t.join()
 
@@ -668,8 +671,9 @@
         req.cnx.commit()
         req = self.request()
         req.create_entity('Note', type=u'todo', inline1=a01)
-        ex = self.assertRaises(ValidationError, req.cnx.commit)
-        self.assertEqual(ex.errors, {'inline1-subject': u'RQLUniqueConstraint S type T, S inline1 A1, A1 todo_by C, Y type T, Y inline1 A2, A2 todo_by C failed'})
+        with self.assertRaises(ValidationError) as cm:
+            req.cnx.commit()
+        self.assertEqual(cm.exception.errors, {'inline1-subject': u'RQLUniqueConstraint S type T, S inline1 A1, A1 todo_by C, Y type T, Y inline1 A2, A2 todo_by C failed'})
 
 if __name__ == '__main__':
     unittest_main()
--- a/server/test/unittest_storage.py	Fri Jan 07 18:51:50 2011 +0100
+++ b/server/test/unittest_storage.py	Mon Jan 10 12:28:09 2011 +0100
@@ -123,34 +123,34 @@
             self.create_file()
 
     def test_source_mapped_attribute_error_cases(self):
-        ex = self.assertRaises(QueryError, self.execute,
-                               'Any X WHERE X data ~= "hop", X is File')
-        self.assertEqual(str(ex), 'can\'t use File.data (X data ILIKE "hop") in restriction')
-        ex = self.assertRaises(QueryError, self.execute,
-                               'Any X, Y WHERE X data D, Y data D, '
-                               'NOT X identity Y, X is File, Y is File')
-        self.assertEqual(str(ex), "can't use D as a restriction variable")
+        with self.assertRaises(QueryError) as cm:
+            self.execute('Any X WHERE X data ~= "hop", X is File')
+        self.assertEqual(str(cm.exception), 'can\'t use File.data (X data ILIKE "hop") in restriction')
+        with self.assertRaises(QueryError) as cm:
+            self.execute('Any X, Y WHERE X data D, Y data D, '
+                         'NOT X identity Y, X is File, Y is File')
+        self.assertEqual(str(cm.exception), "can't use D as a restriction variable")
         # query returning mix of mapped / regular attributes (only file.data
         # mapped, not image.data for instance)
-        ex = self.assertRaises(QueryError, self.execute,
-                               'Any X WITH X BEING ('
-                               ' (Any NULL)'
-                               '  UNION '
-                               ' (Any D WHERE X data D, X is File)'
-                               ')')
-        self.assertEqual(str(ex), 'query fetch some source mapped attribute, some not')
-        ex = self.assertRaises(QueryError, self.execute,
-                               '(Any D WHERE X data D, X is File)'
-                               ' UNION '
-                               '(Any D WHERE X title D, X is Bookmark)')
-        self.assertEqual(str(ex), 'query fetch some source mapped attribute, some not')
+        with self.assertRaises(QueryError) as cm:
+            self.execute('Any X WITH X BEING ('
+                         ' (Any NULL)'
+                         '  UNION '
+                         ' (Any D WHERE X data D, X is File)'
+                         ')')
+        self.assertEqual(str(cm.exception), 'query fetch some source mapped attribute, some not')
+        with self.assertRaises(QueryError) as cm:
+            self.execute('(Any D WHERE X data D, X is File)'
+                         ' UNION '
+                         '(Any D WHERE X title D, X is Bookmark)')
+        self.assertEqual(str(cm.exception), 'query fetch some source mapped attribute, some not')
 
         storages.set_attribute_storage(self.repo, 'State', 'name',
                                        storages.BytesFileSystemStorage(self.tempdir))
         try:
-            ex = self.assertRaises(QueryError,
-                                   self.execute, 'Any D WHERE X name D, X is IN (State, Transition)')
-            self.assertEqual(str(ex), 'query fetch some source mapped attribute, some not')
+            with self.assertRaises(QueryError) as cm:
+                self.execute('Any D WHERE X name D, X is IN (State, Transition)')
+            self.assertEqual(str(cm.exception), 'query fetch some source mapped attribute, some not')
         finally:
             storages.unset_attribute_storage(self.repo, 'State', 'name')
 
@@ -181,10 +181,10 @@
         self.assertEqual(rset[1][0], f1.eid)
         self.assertEqual(rset[0][1], len('the-data'))
         self.assertEqual(rset[1][1], len('the-data'))
-        ex = self.assertRaises(QueryError, self.execute,
-                               'Any X,UPPER(D) WHERE X eid %(x)s, X data D',
-                               {'x': f1.eid})
-        self.assertEqual(str(ex), 'UPPER can not be called on mapped attribute')
+        with self.assertRaises(QueryError) as cm:
+            self.execute('Any X,UPPER(D) WHERE X eid %(x)s, X data D',
+                         {'x': f1.eid})
+        self.assertEqual(str(cm.exception), 'UPPER can not be called on mapped attribute')
 
 
     def test_bfss_fs_importing_transparency(self):
--- a/server/test/unittest_undo.py	Fri Jan 07 18:51:50 2011 +0100
+++ b/server/test/unittest_undo.py	Mon Jan 10 12:28:09 2011 +0100
@@ -212,9 +212,10 @@
         self.assertEqual(errors,
                           [u"Can't restore relation in_group, object entity "
                           "%s doesn't exist anymore." % g.eid])
-        ex = self.assertRaises(ValidationError, self.commit)
-        self.assertEqual(ex.entity, self.toto.eid)
-        self.assertEqual(ex.errors,
+        with self.assertRaises(ValidationError) as cm:
+            self.commit()
+        self.assertEqual(cm.exception.entity, self.toto.eid)
+        self.assertEqual(cm.exception.errors,
                           {'in_group-subject': u'at least one relation in_group is '
                            'required on CWUser (%s)' % self.toto.eid})
 
@@ -252,10 +253,10 @@
                                             value=u'text/html')
         tutu.set_relations(use_email=email, reverse_for_user=prop)
         self.commit()
-        ex = self.assertRaises(ValidationError,
-                               self.cnx.undo_transaction, txuuid)
-        self.assertEqual(ex.entity, tutu.eid)
-        self.assertEqual(ex.errors,
+        with self.assertRaises(ValidationError) as cm:
+            self.cnx.undo_transaction(txuuid)
+        self.assertEqual(cm.exception.entity, tutu.eid)
+        self.assertEqual(cm.exception.errors,
                           {None: 'some later transaction(s) touch entity, undo them first'})
 
     def test_undo_creation_integrity_2(self):
@@ -265,17 +266,17 @@
         session.execute('DELETE U in_group G WHERE U eid %(x)s', {'x': self.toto.eid})
         self.toto.set_relations(in_group=g)
         self.commit()
-        ex = self.assertRaises(ValidationError,
-                               self.cnx.undo_transaction, txuuid)
-        self.assertEqual(ex.entity, g.eid)
-        self.assertEqual(ex.errors,
+        with self.assertRaises(ValidationError) as cm:
+            self.cnx.undo_transaction(txuuid)
+        self.assertEqual(cm.exception.entity, g.eid)
+        self.assertEqual(cm.exception.errors,
                           {None: 'some later transaction(s) touch entity, undo them first'})
         # self.assertEqual(errors,
         #                   [u"Can't restore relation in_group, object entity "
         #                   "%s doesn't exist anymore." % g.eid])
-        # ex = self.assertRaises(ValidationError, self.commit)
-        # self.assertEqual(ex.entity, self.toto.eid)
-        # self.assertEqual(ex.errors,
+        # with self.assertRaises(ValidationError) as cm: self.commit()
+        # self.assertEqual(cm.exception.entity, self.toto.eid)
+        # self.assertEqual(cm.exception.errors,
         #                   {'in_group-subject': u'at least one relation in_group is '
         #                    'required on CWUser (%s)' % self.toto.eid})
 
--- a/test/unittest_schema.py	Fri Jan 07 18:51:50 2011 +0100
+++ b/test/unittest_schema.py	Mon Jan 10 12:28:09 2011 +0100
@@ -17,6 +17,8 @@
 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
 """unit tests for module cubicweb.schema"""
 
+from __future__ import with_statement
+
 import sys
 from os.path import join, isabs, basename, dirname
 
@@ -279,9 +281,9 @@
 
     def _test(self, schemafile, msg):
         self.loader.handle_file(join(DATADIR, schemafile))
-        ex = self.assertRaises(BadSchemaDefinition,
-                               self.loader._build_schema, 'toto', False)
-        self.assertEqual(str(ex), msg)
+        with self.assertRaises(BadSchemaDefinition) as cm:
+            self.loader._build_schema('toto', False)
+        self.assertEqual(str(cm.exception), msg)
 
     def test_rrqlexpr_on_etype(self):
         self._test('rrqlexpr_on_eetype.py',
--- a/web/test/unittest_application.py	Fri Jan 07 18:51:50 2011 +0100
+++ b/web/test/unittest_application.py	Mon Jan 10 12:28:09 2011 +0100
@@ -298,8 +298,9 @@
 
     def test_login_not_available_to_authenticated(self):
         req = self.request()
-        ex = self.assertRaises(Unauthorized, self.app_publish, req, 'login')
-        self.assertEqual(str(ex), 'log out first')
+        with self.assertRaises(Unauthorized) as cm:
+            self.app_publish(req, 'login')
+        self.assertEqual(str(cm.exception), 'log out first')
 
     def test_fb_login_concept(self):
         """see data/views.py"""
--- a/web/test/unittest_views_basecontrollers.py	Fri Jan 07 18:51:50 2011 +0100
+++ b/web/test/unittest_views_basecontrollers.py	Mon Jan 10 12:28:09 2011 +0100
@@ -47,8 +47,9 @@
     def test_noparam_edit(self):
         """check behaviour of this controller without any form parameter
         """
-        ex = self.assertRaises(ValidationError, self.ctrl_publish, self.request())
-        self.assertEqual(ex.errors, {None: u'no selected entities'})
+        with self.assertRaises(ValidationError) as cm:
+            self.ctrl_publish(self.request())
+        self.assertEqual(cm.exception.errors, {None: u'no selected entities'})
 
     def test_validation_unique(self):
         """test creation of two linked entities
@@ -61,8 +62,9 @@
                     'upassword-subject:X': u'toto',
                     'upassword-subject-confirm:X': u'toto',
                     }
-        ex = self.assertRaises(ValidationError, self.ctrl_publish, req)
-        self.assertEqual(ex.errors, {'login-subject': 'the value "admin" is already used, use another one'})
+        with self.assertRaises(ValidationError) as cm:
+            self.ctrl_publish(req)
+        self.assertEqual(cm.exception.errors, {'login-subject': 'the value "admin" is already used, use another one'})
 
     def test_user_editing_itself(self):
         """checking that a manager user can edit itself
@@ -205,8 +207,9 @@
                     'login-subject:X': u'toto',
                     'upassword-subject:X': u'toto',
                     }
-        ex = self.assertRaises(ValidationError, self.ctrl_publish, req)
-        self.assertEqual(ex.errors, {'upassword-subject': u'password and confirmation don\'t match'})
+        with self.assertRaises(ValidationError) as cm:
+            self.ctrl_publish(req)
+        self.assertEqual(cm.exception.errors, {'upassword-subject': u'password and confirmation don\'t match'})
         req = self.request()
         req.form = {'__cloned_eid:X': u(user.eid),
                     'eid': 'X', '__type:X': 'CWUser',
@@ -215,8 +218,9 @@
                     'upassword-subject:X': u'toto',
                     'upassword-subject-confirm:X': u'tutu',
                     }
-        ex = self.assertRaises(ValidationError, self.ctrl_publish, req)
-        self.assertEqual(ex.errors, {'upassword-subject': u'password and confirmation don\'t match'})
+        with self.assertRaises(ValidationError) as cm:
+            self.ctrl_publish(req)
+        self.assertEqual(cm.exception.errors, {'upassword-subject': u'password and confirmation don\'t match'})
 
 
     def test_interval_bound_constraint_success(self):
@@ -230,8 +234,9 @@
                     'amount-subject:X': u'-10',
                     'described_by_test-subject:X': u(feid),
                 }
-        ex = self.assertRaises(ValidationError, self.ctrl_publish, req)
-        self.assertEqual(ex.errors, {'amount-subject': 'value must be >= 0'})
+        with self.assertRaises(ValidationError) as cm:
+            self.ctrl_publish(req)
+        self.assertEqual(cm.exception.errors, {'amount-subject': 'value must be >= 0'})
         req = self.request(rollbackfirst=True)
         req.form = {'eid': ['X'],
                     '__type:X': 'Salesterm',
@@ -239,8 +244,9 @@
                     'amount-subject:X': u'110',
                     'described_by_test-subject:X': u(feid),
                     }
-        ex = self.assertRaises(ValidationError, self.ctrl_publish, req)
-        self.assertEqual(ex.errors, {'amount-subject': 'value must be <= 100'})
+        with self.assertRaises(ValidationError) as cm:
+            self.ctrl_publish(req)
+        self.assertEqual(cm.exception.errors, {'amount-subject': 'value must be <= 100'})
         req = self.request(rollbackfirst=True)
         req.form = {'eid': ['X'],
                     '__type:X': 'Salesterm',
@@ -421,8 +427,9 @@
                     'alias-subject:Y': u'',
                     'use_email-object:Y': 'X',
                     }
-        ex = self.assertRaises(ValidationError, self.ctrl_publish, req)
-        self.assertEqual(ex.errors, {'address-subject': u'required field'})
+        with self.assertRaises(ValidationError) as cm:
+            self.ctrl_publish(req)
+        self.assertEqual(cm.exception.errors, {'address-subject': u'required field'})
 
     def test_nonregr_copy(self):
         user = self.user()