|
- import importlib
- import importlib.util
- import inspect
- import logging
- import sys
- import threading
- from pathlib import Path
- from unittest import case
-
- from .. import tools
- from .tag_selector import TagsSelector
- from .suite import OdooSuite
- from .result import OdooTestResult
-
-
- _logger = logging.getLogger(__name__)
-
-
- def get_module_test_cases(module):
- """Return a suite of all test cases contained in the given module"""
- for obj in module.__dict__.values():
- if not isinstance(obj, type):
- continue
- if not issubclass(obj, case.TestCase):
- continue
- if obj.__module__ != module.__name__:
- continue
-
- test_case_class = obj
- test_cases = test_case_class.__dict__.items()
- if getattr(test_case_class, 'allow_inherited_tests_method', False):
- # keep iherited method for specific classes.
- # This is likely to be removed once a better solution is found
- test_cases = inspect.getmembers(test_case_class, callable)
- else:
- # sort test case to keep the initial behaviour.
- # This is likely to be removed in the future
- test_cases = sorted(test_cases, key=lambda pair: pair[0])
-
- for method_name, method in test_cases:
- if not callable(method):
- continue
- if not method_name.startswith('test'):
- continue
- yield test_case_class(method_name)
-
-
- def get_test_modules(module):
- """ Return a list of module for the addons potentially containing tests to
- feed get_module_test_cases() """
- results = _get_tests_modules(importlib.util.find_spec(f'odoo.addons.{module}'))
- results += list(_get_upgrade_test_modules(module))
-
- return results
-
-
- def _get_tests_modules(mod):
- spec = importlib.util.find_spec('.tests', mod.name)
- if not spec:
- return []
-
- tests_mod = importlib.import_module(spec.name)
- return [
- mod_obj
- for name, mod_obj in inspect.getmembers(tests_mod, inspect.ismodule)
- if name.startswith('test_')
- ]
-
-
- def _get_upgrade_test_modules(module):
- upgrade_modules = (
- f"odoo.upgrade.{module}",
- f"odoo.addons.{module}.migrations",
- f"odoo.addons.{module}.upgrades",
- )
- for module_name in upgrade_modules:
- if not importlib.util.find_spec(module_name):
- continue
-
- upg = importlib.import_module(module_name)
- for path in map(Path, upg.__path__):
- for test in path.glob("tests/test_*.py"):
- spec = importlib.util.spec_from_file_location(f"{upg.__name__}.tests.{test.stem}", test)
- if not spec:
- continue
- pymod = importlib.util.module_from_spec(spec)
- sys.modules[spec.name] = pymod
- spec.loader.exec_module(pymod)
- yield pymod
-
-
- def make_suite(module_names, position='at_install'):
- """ Creates a test suite for all the tests in the specified modules,
- filtered by the provided ``position`` and the current test tags
-
- :param list[str] module_names: modules to load tests from
- :param str position: "at_install" or "post_install"
- """
- config_tags = TagsSelector(tools.config['test_tags'])
- position_tag = TagsSelector(position)
- tests = (
- t
- for module_name in module_names
- for m in get_test_modules(module_name)
- for t in get_module_test_cases(m)
- if position_tag.check(t) and config_tags.check(t)
- )
- return OdooSuite(sorted(tests, key=lambda t: t.test_sequence))
-
-
- def run_suite(suite):
- # avoid dependency hell
- from ..modules import module
- module.current_test = True
- threading.current_thread().testing = True
-
- results = OdooTestResult()
- suite(results)
-
- threading.current_thread().testing = False
- module.current_test = False
- return results
|