[FIX] tests: make sure that a failed tests does not leave the environment dirty
When a failure occurs, or when exiting an assertRaises(), the environment should not contain fields to recompute.
This commit is contained in:
parent
2052c16d21
commit
908252ec88
|
@ -111,12 +111,10 @@ class TestACL(common.TransactionCase):
|
|||
# accessing fields must no raise exceptions...
|
||||
part.name
|
||||
# ... except if they are restricted
|
||||
with self.assertRaises(openerp.osv.orm.except_orm) as cm:
|
||||
with self.assertRaises(openerp.exceptions.AccessError):
|
||||
with mute_logger('openerp.models'):
|
||||
part.email
|
||||
|
||||
self.assertEqual(cm.exception.args[0], 'AccessError')
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest2.main()
|
||||
|
||||
|
|
|
@ -185,6 +185,9 @@ class TestNewFields(common.TransactionCase):
|
|||
with self.assertRaises(Exception):
|
||||
self.env['test_new_api.message'].create({'discussion': discussion.id, 'body': 'Whatever'})
|
||||
|
||||
# make sure that assertRaises() does not leave fields to recompute
|
||||
self.assertFalse(self.env.has_todo())
|
||||
|
||||
# put back oneself into discussion participants: now we can create
|
||||
# messages in discussion
|
||||
discussion.participants += self.env.user
|
||||
|
|
|
@ -815,6 +815,24 @@ class Environment(object):
|
|||
env.computed.clear()
|
||||
env.dirty.clear()
|
||||
|
||||
def clear(self):
|
||||
""" Clear all record caches, and discard all fields to recompute.
|
||||
This may be useful when recovering from a failed ORM operation.
|
||||
"""
|
||||
self.invalidate_all()
|
||||
self.all.todo.clear()
|
||||
|
||||
@contextmanager
|
||||
def clear_upon_failure(self):
|
||||
""" Context manager that clears the environments (caches and fields to
|
||||
recompute) upon exception.
|
||||
"""
|
||||
try:
|
||||
yield
|
||||
except Exception:
|
||||
self.clear()
|
||||
raise
|
||||
|
||||
def field_todo(self, field):
|
||||
""" Check whether `field` must be recomputed, and returns a recordset
|
||||
with all records to recompute for `field`.
|
||||
|
|
|
@ -16,6 +16,7 @@ import time
|
|||
import unittest2
|
||||
import urllib2
|
||||
import xmlrpclib
|
||||
from contextlib import contextmanager
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
import werkzeug
|
||||
|
@ -104,6 +105,20 @@ class BaseCase(unittest2.TestCase):
|
|||
module, xid = xid.split('.')
|
||||
return self.registry('ir.model.data').get_object(self.cr, self.uid, module, xid)
|
||||
|
||||
@contextmanager
|
||||
def _assertRaises(self, exception):
|
||||
""" Context manager that clears the environment upon failure. """
|
||||
with super(BaseCase, self).assertRaises(exception):
|
||||
with self.env.clear_upon_failure():
|
||||
yield
|
||||
|
||||
def assertRaises(self, exception, func=None, *args, **kwargs):
|
||||
if func:
|
||||
with self._assertRaises(exception):
|
||||
func(*args, **kwargs)
|
||||
else:
|
||||
return self._assertRaises(exception)
|
||||
|
||||
|
||||
class TransactionCase(BaseCase):
|
||||
""" TestCase in which each test method is run in its own transaction,
|
||||
|
@ -120,6 +135,8 @@ class TransactionCase(BaseCase):
|
|||
self.env = api.Environment(self.cr, self.uid, {})
|
||||
|
||||
def tearDown(self):
|
||||
# rollback and close the cursor, and reset the environments
|
||||
self.env.reset()
|
||||
self.cr.rollback()
|
||||
self.cr.close()
|
||||
|
||||
|
@ -139,9 +156,12 @@ class SingleTransactionCase(BaseCase):
|
|||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
# rollback and close the cursor, and reset the environments
|
||||
cls.env.reset()
|
||||
cls.cr.rollback()
|
||||
cls.cr.close()
|
||||
|
||||
|
||||
class RedirectHandler(urllib2.HTTPRedirectHandler):
|
||||
"""
|
||||
HTTPRedirectHandler is predicated upon HTTPErrorProcessor being used and
|
||||
|
|
Loading…
Reference in New Issue