Merge lp:~anybox/openobject-server/7.0-test-report into lp:openobject-server/7.0

Proposed by Georges Racinet
Status: Needs review
Proposed branch: lp:~anybox/openobject-server/7.0-test-report
Merge into: lp:openobject-server/7.0
Diff against target: 142 lines (+45/-17)
4 files modified
openerp/modules/loading.py (+12/-4)
openerp/tools/assertion_report.py (+12/-4)
openerp/tools/convert.py (+12/-8)
openerp/tools/yaml_import.py (+9/-1)
To merge this branch: bzr merge lp:~anybox/openobject-server/7.0-test-report
Reviewer Review Type Date Requested Status
OpenERP Core Team Pending
Review via email: mp+208008@code.launchpad.net

Description of the change

Simple way to have assertion_report record more information.

Here is the output I get after deliberately breaking a YML test file in the crm module, with ``oe initialize -d tmp --tests --module crm``, from the branch at lp:~anybox/openerp-command/7.0-initialize-test-report

(...long log...)
2014-02-24 20:17:15,303 3680 INFO tmp openerp.osv.orm: Computing parent left and right for table res_partner_category...

FAIL : 1 failure(s) or error(s) have been recorded
Module crm, in test file u'test/phonecalls.yml': Assertion "Phone call held." FAILED
test: state == "pendinsg"
values: ! pending == pendinsg

To post a comment you must log in.
5247. By Georges Racinet <email address hidden>

  [FIX] platform independency by using openerp.module.module API

Unmerged revisions

5247. By Georges Racinet <email address hidden>

  [FIX] platform independency by using openerp.module.module API

5246. By Georges Racinet <email address hidden>

[IMP] Improved reporting of test failures

While loading modules with the tests option, it's useful to have a report that
display test problems separately from the main log. It's then up to the
launching system (for instance openerpcommand) to produce meaningful user
output.

This would ease I hope the maintainers task in case of regressions by letting
them dispatch easily to people that happen to know the relevant modules
(together with the author of the commit that triggered the error)

A corresponding patch for openerpcommand has already been uploaded.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'openerp/modules/loading.py'
2--- openerp/modules/loading.py 2013-10-31 19:32:28 +0000
3+++ openerp/modules/loading.py 2014-03-04 14:20:49 +0000
4@@ -197,13 +197,21 @@
5 # 'data' section, but should probably not alter the data,
6 # as there is no rollback.
7 if tools.config.options['test_enable']:
8- report.record_result(load_test(module_name, idref, mode))
9-
10+ report.record_result(load_test(module_name, idref, mode),
11+ details=(dict(module=module_name,
12+ msg="Exception during load of legacy "
13+ "data-based tests (yml...)")))
14 # Run the `fast_suite` and `checks` tests given by the module.
15 if module_name == 'base':
16 # Also run the core tests after the database is created.
17- report.record_result(openerp.modules.module.run_unit_tests('openerp'))
18- report.record_result(openerp.modules.module.run_unit_tests(module_name))
19+ report.record_result(openerp.modules.module.run_unit_tests('openerp'),
20+ details=dict(module='openerp',
21+ msg="Failure or error in server core "
22+ "unit tests"))
23+ report.record_result(openerp.modules.module.run_unit_tests(module_name),
24+ details=dict(module=module_name,
25+ msg="Failure or error in unit tests, "
26+ "check logs for more details"))
27
28 processed_modules.append(package.name)
29
30
31=== modified file 'openerp/tools/assertion_report.py'
32--- openerp/tools/assertion_report.py 2012-03-02 11:02:27 +0000
33+++ openerp/tools/assertion_report.py 2014-03-04 14:20:49 +0000
34@@ -8,20 +8,28 @@
35 def __init__(self):
36 self.successes = 0
37 self.failures = 0
38+ self.failures_details = []
39
40 def record_success(self):
41 self.successes += 1
42
43- def record_failure(self):
44+ def record_failure(self, details=None):
45 self.failures += 1
46-
47- def record_result(self, result):
48+ if details is not None:
49+ self.failures_details.append(details)
50+
51+ def record_result(self, result, details=None):
52+ """Record either success or failure, with the provided details in the latter case.
53+
54+ :param result: a boolean
55+ :param details: a dict with keys ``'module'``, ``'testfile'``, ``'msg'``, ``'msg_args'``
56+ """
57 if result is None:
58 pass
59 elif result is True:
60 self.record_success()
61 elif result is False:
62- self.record_failure()
63+ self.record_failure(details=details)
64
65 def __str__(self):
66 res = 'Assertions report: %s successes, %s failures' % (self.successes, self.failures)
67
68=== modified file 'openerp/tools/convert.py'
69--- openerp/tools/convert.py 2013-12-03 09:24:33 +0000
70+++ openerp/tools/convert.py 2014-03-04 14:20:49 +0000
71@@ -692,13 +692,15 @@
72 if rec_src_count:
73 count = int(rec_src_count)
74 if len(ids) != count:
75- self.assertion_report.record_failure()
76 msg = 'assertion "%s" failed!\n' \
77 ' Incorrect search count:\n' \
78 ' expected count: %d\n' \
79- ' obtained count: %d\n' \
80- % (rec_string, count, len(ids))
81- _logger.error(msg)
82+ ' obtained count: %d\n'
83+ msg_args = (rec_string, count, len(ids))
84+ _logger.error(msg, msg_args)
85+ self.assertion_report.record_failure(details=dict(module=self.module,
86+ msg=msg,
87+ msg_args=msg_args))
88 return
89
90 assert ids is not None,\
91@@ -720,13 +722,15 @@
92 expected_value = _eval_xml(self, test, self.pool, cr, uid, self.idref, context=context) or True
93 expression_value = unsafe_eval(f_expr, globals_dict)
94 if expression_value != expected_value: # assertion failed
95- self.assertion_report.record_failure()
96 msg = 'assertion "%s" failed!\n' \
97 ' xmltag: %s\n' \
98 ' expected value: %r\n' \
99- ' obtained value: %r\n' \
100- % (rec_string, etree.tostring(test), expected_value, expression_value)
101- _logger.error(msg)
102+ ' obtained value: %r\n'
103+ msg_args = (rec_string, etree.tostring(test), expected_value, expression_value)
104+ self.assertion_report.record_failure(details=dict(module=self.module,
105+ msg=msg,
106+ msg_args=msg_args))
107+ _logger.error(msg, msg_args)
108 return
109 else: # all tests were successful for this assertion tag (no break)
110 self.assertion_report.record_success()
111
112=== modified file 'openerp/tools/yaml_import.py'
113--- openerp/tools/yaml_import.py 2012-12-01 11:35:24 +0000
114+++ openerp/tools/yaml_import.py 2014-03-04 14:20:49 +0000
115@@ -1,10 +1,12 @@
116 # -*- coding: utf-8 -*-
117+import os
118 import threading
119 import types
120 import time # used to eval time.strftime expressions
121 from datetime import datetime, timedelta
122 import logging
123
124+from copy import deepcopy
125 import openerp.pooler as pooler
126 import openerp.sql_db as sql_db
127 import misc
128@@ -193,7 +195,13 @@
129 return node
130
131 def _log_assert_failure(self, msg, *args):
132- self.assertion_report.record_failure()
133+ from openerp.modules import module # cannot be made before (loop)
134+ basepath = module.get_module_path(self.module)
135+ self.assertion_report.record_failure(
136+ details=dict(module=self.module,
137+ testfile=os.path.relpath(self.filename, basepath),
138+ msg=msg,
139+ msg_args=deepcopy(args)))
140 _logger.error(msg, *args)
141
142 def _get_assertion_id(self, assertion):