2 Execute the unittest2 tests available in OpenERP addons.
11 def get_test_modules(module, submodule, explode):
13 Return a list of submodules containing tests.
16 - the name of a submodule
20 # Turn command-line module, submodule into importable names.
23 elif module == 'openerp':
24 module = 'openerp.tests'
26 module = 'openerp.addons.' + module + '.tests'
28 # Try to import the module
33 print 'Can not `import %s`.' % module
38 if str(e) == 'No module named tests':
39 # It seems the module has no `tests` sub-module, no problem.
42 print 'Can not `import %s`.' % module
45 # Discover available test sub-modules.
46 m = sys.modules[module]
47 submodule_names = sorted([x for x in dir(m) \
48 if x.startswith('test_') and \
49 isinstance(getattr(m, x), types.ModuleType)])
50 submodules = [getattr(m, x) for x in submodule_names]
52 def show_submodules_and_exit():
54 print 'Available submodules are:'
55 for x in submodule_names:
59 fast_suite = getattr(m, 'fast_suite', [])
60 checks = getattr(m, 'checks', [])
62 # Use auto-discovered sub-modules.
64 elif submodule == '__fast_suite__':
65 # `suite` was used before the 6.1 release instead of `fast_suite`.
66 ms = fast_suite if hasattr(m, 'fast_suite') else getattr(m, 'suite', None)
69 print 'The module `%s` has no defined test suite.' % (module,)
70 show_submodules_and_exit()
73 elif submodule == '__sanity_checks__':
77 print 'The module `%s` has no defined sanity checks.' % (module,)
78 show_submodules_and_exit()
81 elif submodule == '__slow_suite__':
82 ms = list(set(submodules).difference(fast_suite, checks))
84 # Pick the command-line-specified test sub-module.
85 m = getattr(m, submodule, None)
90 print 'The module `%s` has no submodule named `%s`.' % \
92 show_submodules_and_exit()
103 config = openerp.tools.config
104 config['db_name'] = args.database
106 config['xmlrpc_port'] = int(args.port)
107 config['admin_passwd'] = 'admin'
108 config['db_password'] = 'a2aevl8w' # TODO from .openerpserverrc
111 args.addons = args.addons.replace(':',',').split(',')
115 config['addons_path'] = ','.join(args.addons)
118 openerp.netsvc.init_alternative_logger()
119 logging.getLogger('openerp').setLevel(logging.CRITICAL)
121 # Install the import hook, to import openerp.addons.<module>.
122 openerp.modules.module.initialize_sys_path()
125 submodule = args.submodule
127 # Import the necessary modules and get the corresponding suite.
130 modules = common.get_addons_from_paths(args.addons, []) # TODO openerp.addons.base is not included ?
132 for module in ['openerp'] + modules:
134 get_test_modules(module, submodule, explode=False))
136 test_modules = get_test_modules(module, submodule, explode=True)
138 print 'Test modules:'
139 for test_module in test_modules:
140 print ' ', test_module.__name__
144 suite = unittest2.TestSuite()
145 for test_module in test_modules:
146 suite.addTests(unittest2.TestLoader().loadTestsFromModule(test_module))
147 r = unittest2.TextTestRunner(verbosity=2).run(suite)
148 if r.errors or r.failures:
151 def add_parser(subparsers):
152 parser = subparsers.add_parser('run-tests',
153 description='Run the OpenERP server and/or addons tests.')
154 parser.add_argument('-d', '--database', metavar='DATABASE', required=True,
155 help='the database to test. Depending on the test suites, the '
156 'database must already exist or not.')
157 parser.add_argument('-p', '--port', metavar='PORT',
158 help='the port used for WML-RPC tests')
159 common.add_addons_argument(parser)
162 '-m', '--module', metavar='MODULE', action=ModuleAction, default=None,
163 help="the module to test in `module[.submodule]` notation. "
164 "Use `openerp` for the core OpenERP tests. "
165 "Leave empty to run every declared tests. "
166 "Give a module but no submodule to run all the module's declared "
167 "tests. If both the module and the submodule are given, "
168 "the sub-module can be run even if it is not declared in the module.")
169 group = parser.add_mutually_exclusive_group()
172 dest='submodule', action=GuardAction, nargs=0, const='__fast_suite__',
173 help='run only the tests explicitly declared in the fast suite (this '
174 'makes sense only with the bare `module` notation or no module at '
178 dest='submodule', action=GuardAction, nargs=0, const='__sanity_checks__',
179 help='run only the sanity check tests')
182 dest='submodule', action=GuardAction, nargs=0, const='__slow_suite__',
183 help="Only run slow tests (tests which are neither in the fast nor in"
184 " the sanity suite)")
185 parser.add_argument('--dry-run', action='store_true',
186 help='do not run the tests')
188 parser.set_defaults(run=run, submodule=None)
190 class ModuleAction(argparse.Action):
191 def __call__(self, parser, namespace, values, option_string=None):
192 split = values.split('.')
194 module, submodule = values, None
195 elif len(split) == 2:
196 module, submodule = split
198 raise argparse.ArgumentError(
200 "must have the form 'module[.submodule]', got '%s'" % values)
202 setattr(namespace, self.dest, module)
203 if submodule is not None:
204 setattr(namespace, 'submodule', submodule)
206 class GuardAction(argparse.Action):
207 def __call__(self, parser, namespace, values, option_string=None):
208 if getattr(namespace, self.dest, None):
209 print "%s value provided, ignoring '%s'" % (self.dest, option_string)
211 setattr(namespace, self.dest, self.const)