summaryrefslogtreecommitdiff
path: root/odoo/tests/common.py
diff options
context:
space:
mode:
Diffstat (limited to 'odoo/tests/common.py')
-rw-r--r--odoo/tests/common.py45
1 files changed, 39 insertions, 6 deletions
diff --git a/odoo/tests/common.py b/odoo/tests/common.py
index e0370cc0f51..0dd6162c320 100644
--- a/odoo/tests/common.py
+++ b/odoo/tests/common.py
@@ -33,7 +33,7 @@ from lxml import etree, html
from odoo.models import BaseModel
from odoo.osv.expression import normalize_domain
-from odoo.tools import single_email_re
+from odoo.tools import float_compare, single_email_re
from odoo.tools.misc import find_in_path
from odoo.tools.safe_eval import safe_eval
@@ -259,7 +259,7 @@ class BaseCase(TreeCase, MetaCase('DummyCase', (object,), {})):
return self._assertRaises(exception)
@contextmanager
- def assertQueryCount(self, default=0, **counters):
+ def assertQueryCount(self, default=0, flush=True, **counters):
""" Context manager that counts queries. It may be invoked either with
one value, or with a set of named arguments like ``login=value``::
@@ -276,8 +276,12 @@ class BaseCase(TreeCase, MetaCase('DummyCase', (object,), {})):
with self.subTest(), patch('random.random', lambda: 1):
login = self.env.user.login
expected = counters.get(login, default)
+ if flush:
+ self.env.user.flush()
count0 = self.cr.sql_log_count
yield
+ if flush:
+ self.env.user.flush()
count = self.cr.sql_log_count - count0
if count != expected:
# add some info on caller to allow semi-automatic update of query count
@@ -293,6 +297,8 @@ class BaseCase(TreeCase, MetaCase('DummyCase', (object,), {})):
logger.info(msg, login, count, expected, funcname, filename, linenum)
else:
yield
+ if flush:
+ self.env.user.flush()
def assertRecordValues(self, records, expected_values):
''' Compare a recordset with a list of dictionaries representing the expected results.
@@ -314,7 +320,8 @@ class BaseCase(TreeCase, MetaCase('DummyCase', (object,), {})):
for field_name in candidate.keys():
record_value = record[field_name]
candidate_value = candidate[field_name]
- field_type = record._fields[field_name].type
+ field = record._fields[field_name]
+ field_type = field.type
if field_type == 'monetary':
# Compare monetary field.
currency_field_name = record._fields[field_name].currency_field
@@ -322,6 +329,8 @@ class BaseCase(TreeCase, MetaCase('DummyCase', (object,), {})):
if record_currency.compare_amounts(candidate_value, record_value)\
if record_currency else candidate_value != record_value:
return False
+ elif field_type == 'float' and field.get_digits(record.env):
+ return not float_compare(candidate_value, record_value, precision_digits=field.get_digits(record.env)[1])
elif field_type in ('one2many', 'many2many'):
# Compare x2many relational fields.
# Empty comparison must be an empty list to be True.
@@ -363,8 +372,13 @@ class BaseCase(TreeCase, MetaCase('DummyCase', (object,), {})):
msg = 'Wrong number of records to compare: %d != %d.\n\n' % (len(records), len(expected_values))
self.fail(msg + _format_message(records, expected_values))
+ candidates = list(expected_values)
for index, record in enumerate(records):
- if not _compare_candidate(record, expected_values[index]):
+ for candidate_index, candidate in enumerate(candidates):
+ if _compare_candidate(record, candidate):
+ candidates.pop(candidate_index)
+ break
+ else:
msg = 'Record doesn\'t match expected values at index %d.\n\n' % index
self.fail(msg + _format_message(records, expected_values))
@@ -425,6 +439,10 @@ class SingleTransactionCase(BaseCase):
cls.cr = cls.registry.cursor()
cls.env = api.Environment(cls.cr, odoo.SUPERUSER_ID, {})
+ def setUp(self):
+ super(SingleTransactionCase, self).setUp()
+ self.env.user.flush()
+
@classmethod
def tearDownClass(cls):
# rollback and close the cursor, and reset the environments
@@ -885,6 +903,7 @@ class HttpCase(TransactionCase):
self.opener.cookies['session_id'] = self.session_id
def url_open(self, url, data=None, files=None, timeout=10, headers=None):
+ self.env['base'].flush()
if url.startswith('/'):
url = "http://%s:%s%s" % (HOST, PORT, url)
if data or files:
@@ -965,6 +984,9 @@ class HttpCase(TransactionCase):
base_url = "http://%s:%s" % (HOST, PORT)
ICP = self.env['ir.config_parameter']
ICP.set_param('web.base.url', base_url)
+ # flush updates to the database before launching the client side,
+ # otherwise they simply won't be visible
+ ICP.flush()
url = "%s%s" % (base_url, url_path or '/')
self._logger.info('Open "%s" in browser', url)
@@ -1003,7 +1025,12 @@ class HttpCase(TransactionCase):
step_delay = ', %s' % step_delay if step_delay else ''
code = kwargs.pop('code', "odoo.startTour('%s'%s)" % (tour_name, step_delay))
ready = kwargs.pop('ready', "odoo.__DEBUG__.services['web_tour.tour'].tours.%s.ready" % tour_name)
- return self.browser_js(url_path=url_path, code=code, ready=ready, **kwargs)
+ res = self.browser_js(url_path=url_path, code=code, ready=ready, **kwargs)
+ # some tests read the result after the tour, and as the tour does not
+ # use this environment's cache, invalidate it to fetch the data from the
+ # database
+ self.env.cache.invalidate()
+ return res
phantom_js = browser_js
@@ -1026,6 +1053,9 @@ def users(*logins):
# switch user and execute func
self.uid = user_id[login]
func(*args, **kwargs)
+ # Invalidate the cache between subtests, in order to not reuse
+ # the former user's cache (`test_read_mail`, `test_write_mail`)
+ self.env.cache.invalidate()
finally:
self.uid = old_uid
@@ -1040,13 +1070,16 @@ def warmup(func, *args, **kwargs):
effects of the warmup phase are rolled back thanks to a savepoint.
"""
self = args[0]
+ self.env['base'].flush()
+ self.env.cache.invalidate()
# run once to warm up the caches
self.warm = False
self.cr.execute('SAVEPOINT test_warmup')
func(*args, **kwargs)
+ self.env['base'].flush()
+ # run once for real
self.cr.execute('ROLLBACK TO SAVEPOINT test_warmup')
self.env.cache.invalidate()
- # run once for real
self.warm = True
func(*args, **kwargs)