How to use get_type_label_mapping method in avocado

Best Python code snippet using avocado_python

loader.py

Source:loader.py Github

copy

Full Screen

...77 """78 List all supported test types (excluding incorrect ones)79 """80 name = plugin.name81 mapping = plugin.get_type_label_mapping()82 # Using __func__ to avoid problem with different term_supp instances83 healthy_func = getattr(output.TERM_SUPPORT.healthy_str, '__func__')84 types = [mapping[_[0]]85 for _ in plugin.get_decorator_mapping().items()86 if _[1].__func__ is healthy_func]87 return [name + '.' + _ for _ in types]88 def _str_loaders():89 """90 :return: string of sorted loaders and types91 """92 out = ""93 for plugin in self.registered_plugins:94 out += " %s: %s\n" % (plugin.name,95 ", ".join(_good_test_types(plugin)))96 return out.rstrip('\n')97 # When running from the JobAPI there is no subcommand98 subcommand = config.get('subcommand') or 'run'99 self.register_plugin(TapLoader)100 # Register external runner when --external-runner is used101 external_runner = config.get("{}.external_runner".format(subcommand))102 if external_runner:103 self.register_plugin(ExternalLoader)104 key = "{}.loaders".format(subcommand)105 default_loaders = {'file', '@DEFAULT'}106 loaders = config.get(key) or default_loaders107 if set(loaders) != default_loaders:108 warnings.warn("The loaders and external-runner are incompatible."109 "The values in loaders will be ignored.",110 RuntimeWarning)111 config[key] = ["external:{}".format(external_runner)]112 else:113 # Add (default) file loader if not already registered114 if FileLoader not in self.registered_plugins:115 self.register_plugin(FileLoader)116 if ExternalLoader not in self.registered_plugins:117 self.register_plugin(ExternalLoader)118 supported_loaders = [_.name for _ in self.registered_plugins]119 supported_types = []120 for plugin in self.registered_plugins:121 supported_types.extend(_good_test_types(plugin))122 # Here is one of the few exceptions that has a hardcoded default123 loaders = config.get("{}.loaders".format(subcommand)) or ['file',124 '@DEFAULT']125 if "@DEFAULT" in loaders: # Replace @DEFAULT with unused loaders126 idx = loaders.index("@DEFAULT")127 loaders = (loaders[:idx] + [plugin for plugin in supported_loaders128 if plugin not in loaders] +129 loaders[idx + 1:])130 # Remove duplicate @DEFAULT entries131 loaders = [item for item in loaders if item != "@DEFAULT"]132 loaders = [_.split(':', 1) for _ in loaders]133 priority = [_[0] for _ in loaders]134 for i, name in enumerate(priority):135 extra_params = {}136 if name in supported_types:137 name, extra_params['allowed_test_types'] = name.split('.', 1)138 elif name not in supported_loaders:139 raise InvalidLoaderPlugin("Unknown loader '%s'. Available "140 "plugins are:\n%s"141 % (name, _str_loaders()))142 if len(loaders[i]) == 2:143 extra_params['loader_options'] = loaders[i][1]144 plugin = self.registered_plugins[supported_loaders.index(name)]145 self._initialized_plugins.append(plugin(config, extra_params))146 def _update_mappings(self):147 """148 Update the mappings according the current initialized plugins149 """150 # Plugins are initialized, let's update mappings151 self._label_mapping = {MissingTest: "MISSING"}152 for plugin in self._initialized_plugins:153 self._label_mapping.update(plugin.get_full_type_label_mapping())154 self._decorator_mapping = {MissingTest:155 output.TERM_SUPPORT.fail_header_str}156 for plugin in self._initialized_plugins:157 self._decorator_mapping.update(plugin.get_full_decorator_mapping())158 def get_extra_listing(self):159 for loader_plugin in self._initialized_plugins:160 loader_plugin.get_extra_listing()161 def get_base_keywords(self):162 base_path = []163 for loader_plugin in self._initialized_plugins:164 base_path += loader_plugin.get_base_keywords()165 return base_path166 def get_type_label_mapping(self):167 if self._label_mapping is None:168 raise RuntimeError("LoaderProxy.discover has to be called before "169 "LoaderProxy.get_type_label_mapping")170 return self._label_mapping171 def get_decorator_mapping(self):172 if self._label_mapping is None:173 raise RuntimeError("LoaderProxy.discover has to be called before "174 "LoaderProxy.get_decorator_mapping")175 return self._decorator_mapping176 def discover(self, references, which_tests=DiscoverMode.DEFAULT, force=None):177 """178 Discover (possible) tests from test references.179 :param references: a list of tests references; if [] use plugin defaults180 :type references: builtin.list181 :param which_tests: Limit tests to be displayed182 :type which_tests: :class:`DiscoverMode`183 :param force: don't raise an exception when some test references184 are not resolved to tests.185 :return: A list of test factories (tuples (TestClass, test_params))186 """187 def handle_exception(plugin, details):188 # FIXME: Introduce avocado.exceptions logger and use here189 stacktrace.log_message("Test discovery plugin %s failed: "190 "%s" % (plugin, details),191 LOG_UI.getChild("exceptions"))192 # FIXME: Introduce avocado.traceback logger and use here193 stacktrace.log_exc_info(sys.exc_info(), LOG_UI.getChild("debug"))194 tests = []195 unhandled_references = []196 if not references:197 for loader_plugin in self._initialized_plugins:198 try:199 tests.extend(loader_plugin.discover(None, which_tests))200 except Exception as details: # pylint: disable=W0703201 handle_exception(loader_plugin, details)202 else:203 for reference in references:204 handled = False205 for loader_plugin in self._initialized_plugins:206 try:207 _test = loader_plugin.discover(reference, which_tests)208 if _test:209 tests.extend(_test)210 handled = True211 if which_tests != DiscoverMode.ALL:212 break # Don't process other plugins213 except Exception as details: # pylint: disable=W0703214 handle_exception(loader_plugin, details)215 if not handled:216 unhandled_references.append(reference)217 if unhandled_references:218 if which_tests == DiscoverMode.ALL:219 tests.extend([(MissingTest, {'name': reference})220 for reference in unhandled_references])221 else:222 # This is a workaround to avoid changing the method signature223 if force is True or force == 'on':224 LOG_UI.error(LoaderUnhandledReferenceError(unhandled_references,225 self._initialized_plugins))226 else:227 raise LoaderUnhandledReferenceError(unhandled_references,228 self._initialized_plugins)229 self._update_mappings()230 return tests231 def load_test(self, test_factory):232 """233 Load test from the test factory.234 :param test_factory: a pair of test class and parameters.235 :type test_factory: tuple236 :return: an instance of :class:`avocado.core.test.Test`.237 """238 test_class, test_parameters = test_factory239 if 'modulePath' in test_parameters:240 test_path = test_parameters.pop('modulePath')241 else:242 test_path = None243 if isinstance(test_class, str):244 module_name = os.path.basename(test_path).split('.')[0]245 test_module_dir = os.path.abspath(os.path.dirname(test_path))246 # Tests with local dir imports need this247 try:248 sys.path.insert(0, test_module_dir)249 f, p, d = imp.find_module(module_name, [test_module_dir])250 test_module = imp.load_module(module_name, f, p, d)251 except: # pylint: disable=W0702252 # On load_module exception we fake the test class and pass253 # the exc_info as parameter to be logged.254 test_parameters['methodName'] = 'test'255 exception = stacktrace.prepare_exc_info(sys.exc_info())256 test_parameters['exception'] = exception257 return test.TestError(**test_parameters)258 finally:259 if test_module_dir in sys.path:260 sys.path.remove(test_module_dir)261 for _, obj in inspect.getmembers(test_module):262 if (inspect.isclass(obj) and obj.__name__ == test_class and263 inspect.getmodule(obj) == test_module):264 if issubclass(obj, test.Test):265 test_class = obj266 break267 if test_class is test.DryRunTest:268 test_parameters['modulePath'] = test_path269 if 'run.results_dir' in test_parameters:270 test_parameters['base_logdir'] = test_parameters.pop('run.results_dir')271 test_instance = test_class(**test_parameters)272 return test_instance273 def clear_plugins(self):274 self.registered_plugins = []275class TestLoader:276 """277 Base for test loader classes278 """279 name = None # Human friendly name of the loader280 def __init__(self, config, extra_params): # pylint: disable=W0613281 if "allowed_test_types" in extra_params:282 mapping = self.get_type_label_mapping()283 types = extra_params.pop("allowed_test_types")284 if len(mapping) != 1:285 msg = ("Loader '%s' supports multiple test types but does not "286 "handle the 'allowed_test_types'. Either don't use "287 "'%s' instead of '%s.%s' or take care of the "288 "'allowed_test_types' in the plugin."289 % (self.name, self.name, self.name, types))290 raise LoaderError(msg)291 elif next(mapping.itervalues()) != types:292 raise LoaderError("Loader '%s' doesn't support test type '%s',"293 " it supports only '%s'"294 % (self.name, types,295 next(mapping.itervalues())))296 if "loader_options" in extra_params:297 raise LoaderError("Loader '%s' doesn't support 'loader_options', "298 "please don't use --loader %s:%s"299 % (self.name, self.name,300 extra_params.get("loader_options")))301 if extra_params:302 raise LoaderError("Loader '%s' doesn't handle extra params %s, "303 "please adjust your plugin to take care of them."304 % (self.name, extra_params))305 self.config = config306 def get_extra_listing(self):307 pass308 @staticmethod309 def get_type_label_mapping():310 """311 Get label mapping for display in test listing.312 :return: Dict {TestClass: 'TEST_LABEL_STRING'}313 """314 raise NotImplementedError315 def get_full_type_label_mapping(self): # pylint: disable=R0201316 """317 Allows extending the type-label-mapping after the object is initialized318 """319 return self.get_type_label_mapping()320 @staticmethod321 def get_decorator_mapping():322 """323 Get label mapping for display in test listing.324 :return: Dict {TestClass: decorator function}325 """326 raise NotImplementedError327 def get_full_decorator_mapping(self): # pylint: disable=R0201328 """329 Allows extending the decorator-mapping after the object is initialized330 """331 return self.get_decorator_mapping()332 def discover(self, reference, which_tests=DiscoverMode.DEFAULT):333 """334 Discover (possible) tests from an reference.335 :param reference: the reference to be inspected.336 :type reference: str337 :param which_tests: Limit tests to be displayed338 :type which_tests: :class:`DiscoverMode`339 :return: a list of test matching the reference as params.340 """341 raise NotImplementedError342class BrokenSymlink:343 """ Dummy object to represent reference pointing to a BrokenSymlink path """344class AccessDeniedPath:345 """ Dummy object to represent reference pointing to a inaccessible path """346def add_loader_options(parser, section='run'):347 arggrp = parser.add_argument_group('loader options')348 help_msg = ("Overrides the priority of the test loaders. You can specify "349 "either @loader_name or TEST_TYPE. By default it tries all "350 "available loaders according to priority set in "351 "settings->plugins.loaders.")352 settings.register_option(section=section,353 key='loaders',354 nargs='*',355 key_type=list,356 default=['file', '@DEFAULT'],357 help_msg=help_msg,358 parser=arggrp,359 long_arg='--loaders')360 help_msg = ("Path to an specific test runner that allows the use of its "361 "own tests. This should be used for running tests that do not "362 "conform to Avocado\'s SIMPLE test interface and can not run "363 "standalone. Note: the use of --external-runner overwrites "364 "the --loaders to 'external_runner'")365 settings.register_option(section=section,366 key='external_runner',367 default=None,368 help_msg=help_msg,369 parser=arggrp,370 long_arg='--external-runner')371 help_msg = ("Change directory before executing tests. This option may be "372 "necessary because of requirements and/or limitations of the "373 "external test runner. If the external runner requires to be "374 "run from its own base directory, use 'runner' here. If the "375 "external runner runs tests based on files and requires to "376 "be run from the directory where those files are located, "377 "use 'test' here and specify the test directory with the "378 "option '--external-runner-testdir'.")379 settings.register_option(section=section,380 key='external_runner_chdir',381 help_msg=help_msg,382 default=None,383 parser=arggrp,384 choices=('runner', 'test'),385 long_arg='--external-runner-chdir')386 help_msg = ("Where test files understood by the external test runner "387 "are located in the filesystem. Obviously this assumes and "388 "only applies to external test runners that run tests from "389 "files")390 settings.register_option(section=section,391 key='external_runner_testdir',392 metavar='DIRECTORY',393 default=None,394 help_msg=help_msg,395 parser=arggrp,396 long_arg='--external-runner-testdir')397class NotATest:398 """399 Class representing something that is not a test400 """401class SimpleFileLoader(TestLoader):402 """403 Test loader class.404 """405 name = 'file'406 NOT_TEST_STR = ("Not a supported test")407 def __init__(self, config, extra_params):408 test_type = extra_params.pop('allowed_test_types', None)409 super(SimpleFileLoader, self).__init__(config, extra_params)410 self.test_type = test_type411 @staticmethod412 def get_type_label_mapping():413 return {NotATest: 'NOT_A_TEST',414 MissingTest: 'MISSING',415 BrokenSymlink: 'BROKEN_SYMLINK',416 AccessDeniedPath: 'ACCESS_DENIED'}417 @staticmethod418 def get_decorator_mapping():419 return {NotATest: output.TERM_SUPPORT.warn_header_str,420 MissingTest: output.TERM_SUPPORT.fail_header_str,421 BrokenSymlink: output.TERM_SUPPORT.fail_header_str,422 AccessDeniedPath: output.TERM_SUPPORT.fail_header_str}423 @staticmethod424 def _is_matching_test_class(tst, test_class):425 return issubclass(tst, test_class)426 def discover(self, reference, which_tests=DiscoverMode.DEFAULT):427 """428 Discover (possible) tests from a directory.429 Recursively walk in a directory and find tests params.430 The tests are returned in alphabetic order.431 Afterwards when "allowed_test_types" is supplied it verifies if all432 found tests are of the allowed type. If not return None (even on433 partial match).434 :param reference: the directory path to inspect.435 :param which_tests: Limit tests to be displayed436 :type which_tests: :class:`DiscoverMode`437 :return: list of matching tests438 """439 tests = self._discover(reference, which_tests)440 if self.test_type:441 mapping = self.get_type_label_mapping()442 test_class = next(key for key, value in mapping.items()443 if value == self.test_type)444 for tst in tests:445 if not self._is_matching_test_class(tst[0], test_class):446 return None447 return tests448 def _discover(self, reference, which_tests=DiscoverMode.DEFAULT):449 """450 Recursively walk in a directory and find tests params.451 The tests are returned in alphabetic order.452 :param reference: the directory path to inspect.453 :param which_tests: Limit tests to be displayed454 :type which_tests: :class:`DiscoverMode`455 :return: list of matching tests456 """457 if reference is None:458 if which_tests == DiscoverMode.DEFAULT:459 return [] # Return empty set when not listing details460 else:461 reference = data_dir.get_test_dir()462 ignore_suffix = ('.data', '.pyc', '.pyo', '__init__.py',463 '__main__.py')464 # Look for filename:test_method pattern465 reference, subtests_filter = reference_split(reference)466 if subtests_filter is not None:467 subtests_filter = re.compile(subtests_filter)468 if not os.path.isdir(reference): # Single file469 return self._make_tests(reference, which_tests == DiscoverMode.ALL,470 subtests_filter)471 tests = []472 def add_test_from_exception(exception):473 """ If the exc.filename is valid test it's added to tests """474 tests.extend(self._make_tests(exception.filename,475 which_tests == DiscoverMode.ALL))476 def skip_non_test(exception): # pylint: disable=W0613477 """ Always return None """478 return None479 if which_tests == DiscoverMode.ALL:480 onerror = add_test_from_exception481 else: # DEFAULT, AVAILABLE => skip missing tests482 onerror = skip_non_test483 for dirpath, dirs, filenames in os.walk(reference, onerror=onerror):484 dirs.sort()485 for file_name in sorted(filenames):486 if file_name.startswith('.') or file_name.endswith(ignore_suffix):487 continue488 pth = os.path.join(dirpath, file_name)489 tests.extend(self._make_tests(pth,490 which_tests == DiscoverMode.ALL,491 subtests_filter))492 return tests493 def _make_simple_test(self, test_path, subtests_filter):494 return self._make_test(test.SimpleTest, test_path,495 subtests_filter=subtests_filter,496 executable=test_path)497 def _make_simple_or_broken_test(self, test_path, subtests_filter, make_broken):498 if os.access(test_path, os.X_OK):499 return self._make_simple_test(test_path, subtests_filter)500 else:501 return make_broken(NotATest, test_path,502 self.NOT_TEST_STR)503 def _make_existing_file_tests(self, test_path, make_broken,504 subtests_filter):505 return self._make_simple_or_broken_test(test_path, subtests_filter, make_broken)506 def _make_nonexisting_file_tests(self, test_path, make_broken,507 subtests_filter, test_name): # pylint: disable=W0613508 return make_broken(NotATest, test_name, "File not found "509 "('%s'; '%s')" % (test_name, test_path))510 @staticmethod511 def _make_test(klass, uid, description=None, subtests_filter=None,512 **test_arguments):513 """514 Create test template515 :param klass: test class516 :param uid: test uid (by default used as id and name)517 :param description: Description appended to "uid" (for listing purpose)518 :param subtests_filter: optional filter of methods for avocado tests519 :param test_arguments: arguments to be passed to the klass(test_arguments)520 """521 if subtests_filter and not subtests_filter.search(uid):522 return []523 if description:524 uid = "%s: %s" % (uid, description)525 test_arguments["name"] = uid526 return [(klass, test_arguments)]527 def _make_tests(self, test_path, list_non_tests, subtests_filter=None):528 """529 Create test templates from given path530 :param test_path: File system path531 :param list_non_tests: include bad tests (NotATest, BrokenSymlink,...)532 :param subtests_filter: optional filter of methods for avocado tests533 """534 def ignore_broken(klass, uid, description=None): # pylint: disable=W0613535 """ Always return empty list """536 return []537 if list_non_tests: # return broken test with params538 make_broken = self._make_test539 else: # return empty set instead540 make_broken = ignore_broken541 test_name = test_path542 if os.path.exists(test_path):543 if os.access(test_path, os.R_OK) is False:544 return make_broken(AccessDeniedPath, test_path, "Is not "545 "readable")546 return self._make_existing_file_tests(test_path, make_broken,547 subtests_filter)548 else:549 if os.path.islink(test_path):550 try:551 if not os.path.isfile(os.readlink(test_path)):552 return make_broken(BrokenSymlink, test_path, "Is a "553 "broken symlink")554 except OSError:555 return make_broken(AccessDeniedPath, test_path, "Is not "556 "accessible.")557 return self._make_nonexisting_file_tests(test_path, make_broken,558 subtests_filter,559 test_name)560class FileLoader(SimpleFileLoader):561 """562 Test loader class.563 """564 name = 'file'565 NOT_TEST_STR = ("Not an INSTRUMENTED (avocado.Test based), PyUNITTEST ("566 "unittest.TestCase based) or SIMPLE (executable) test")567 @staticmethod568 def get_type_label_mapping():569 mapping = SimpleFileLoader.get_type_label_mapping()570 mapping.update(571 {test.SimpleTest: 'SIMPLE',572 test.Test: 'INSTRUMENTED',573 test.PythonUnittest: 'PyUNITTEST'})574 return mapping575 @staticmethod576 def get_decorator_mapping():577 mapping = SimpleFileLoader.get_decorator_mapping()578 mapping.update(579 {test.SimpleTest: output.TERM_SUPPORT.healthy_str,580 test.Test: output.TERM_SUPPORT.healthy_str,581 test.PythonUnittest: output.TERM_SUPPORT.healthy_str})582 return mapping583 @staticmethod584 def _is_matching_test_class(tst, test_class):585 if test_class is test.Test:586 # Instrumented tests are defined as string and loaded at the587 # execution time.588 return isinstance(tst, str)589 else:590 return not isinstance(tst, str) and issubclass(tst, test_class)591 def _find_python_unittests(self, test_path, disabled, subtests_filter):592 result = []593 class_methods = safeloader.find_python_unittests(test_path)594 for klass, methods in class_methods.items():595 if klass in disabled:596 continue597 if test_path.endswith(".py"):598 test_path = test_path[:-3]599 test_module_name = os.path.relpath(test_path)600 test_module_name = test_module_name.replace(os.path.sep, ".")601 candidates = [("%s.%s.%s" % (test_module_name, klass, method),602 tags) for (method, tags, _) in methods]603 if subtests_filter:604 result += [_ for _ in candidates if subtests_filter.search(_)]605 else:606 result += candidates607 return result608 def _make_simple_test(self, test_path, subtests_filter):609 return self._make_test(test.SimpleTest, test_path,610 subtests_filter=subtests_filter,611 executable=test_path)612 def _make_simple_or_broken_test(self, test_path, subtests_filter, make_broken):613 if os.access(test_path, os.X_OK):614 # Module does not have an avocado test class inside but615 # it's executable, let's execute it.616 return self._make_simple_test(test_path, subtests_filter)617 else:618 # Module does not have an avocado test class inside, and619 # it's not executable. Not a Test.620 return make_broken(NotATest, test_path,621 self.NOT_TEST_STR)622 def _make_python_file_tests(self, test_path, make_broken,623 subtests_filter, test_name=None):624 if test_name is None:625 test_name = test_path626 try:627 # Avocado tests628 avocado_tests, disabled = safeloader.find_avocado_tests(test_path)629 if avocado_tests:630 test_factories = []631 for test_class, info in avocado_tests.items():632 if isinstance(test_class, str):633 for test_method, tags, _ in info:634 name = test_name + \635 ':%s.%s' % (test_class, test_method)636 if (subtests_filter and637 not subtests_filter.search(name)):638 continue639 tst = (test_class, {'name': name,640 'modulePath': test_path,641 'methodName': test_method,642 'tags': tags})643 test_factories.append(tst)644 return test_factories645 # Python unittests646 old_dir = os.getcwd()647 try:648 py_test_dir = os.path.abspath(os.path.dirname(test_path))649 py_test_name = os.path.basename(test_path)650 os.chdir(py_test_dir)651 python_unittests = self._find_python_unittests(py_test_name,652 disabled,653 subtests_filter)654 finally:655 os.chdir(old_dir)656 if python_unittests:657 return [(test.PythonUnittest, {"name": name,658 "test_dir": py_test_dir,659 "tags": tags})660 for (name, tags) in python_unittests]661 else:662 # Module does not have an avocado test or pyunittest class inside,663 # but maybe it's a Python executable.664 return self._make_simple_or_broken_test(test_path,665 subtests_filter,666 make_broken)667 # Since a lot of things can happen here, the broad exception is668 # justified. The user will get it unadulterated anyway, and avocado669 # will not crash. Ugly python files can raise any exception670 except BaseException as details: # pylint: disable=W0703671 if isinstance(details, KeyboardInterrupt):672 raise # Don't ignore ctrl+c673 else:674 return self._make_simple_or_broken_test(test_path,675 subtests_filter,676 make_broken)677 def _make_existing_file_tests(self, test_path, make_broken,678 subtests_filter):679 if test_path.endswith('.py'):680 return self._make_python_file_tests(test_path, make_broken,681 subtests_filter)682 else:683 return self._make_simple_or_broken_test(test_path,684 subtests_filter,685 make_broken)686 def _make_nonexisting_file_tests(self, test_path, make_broken,687 subtests_filter, test_name):688 # Try to resolve test ID (keep compatibility)689 test_path = os.path.join(data_dir.get_test_dir(), test_name)690 if os.path.exists(test_path):691 return self._make_python_file_tests(test_path, make_broken,692 subtests_filter,693 test_name)694 else:695 if not subtests_filter and ':' in test_name:696 test_name, subtests_filter = test_name.split(':', 1)697 test_path = os.path.join(data_dir.get_test_dir(),698 test_name)699 if os.path.exists(test_path):700 subtests_filter = re.compile(subtests_filter)701 return self._make_python_file_tests(test_path,702 make_broken,703 subtests_filter,704 test_name)705 return make_broken(NotATest, test_name, "File not found "706 "('%s'; '%s')" % (test_name, test_path))707class ExternalLoader(TestLoader):708 """709 External-runner loader class710 """711 name = 'external'712 def __init__(self, config, extra_params):713 loader_options = extra_params.pop('loader_options', None)714 super(ExternalLoader, self).__init__(config, extra_params)715 if loader_options == '?':716 raise LoaderError("File loader accepts an option to set the "717 "external-runner executable.")718 self._external_runner = self._process_external_runner(719 config, loader_options)720 @staticmethod721 def _process_external_runner(config, runner):722 """ Enables the external_runner when asked for """723 subcommand = config.get('subcommand')724 chdir = config.get("{}.external_runner_chdir".format(subcommand))725 test_dir = config.get("{}.external_runner_testdir".format(subcommand))726 if runner:727 external_runner_and_args = shlex.split(runner)728 executable = os.path.abspath(external_runner_and_args[0])729 runner = " ".join([executable] + external_runner_and_args[1:])730 if not os.path.exists(executable):731 msg = ('Could not find the external runner executable "%s"'732 % executable)733 raise LoaderError(msg)734 if chdir == 'test':735 if not test_dir:736 msg = ('Option "--external-runner-chdir=test" requires '737 '"--external-runner-testdir" to be set.')738 raise LoaderError(msg)739 elif test_dir:740 msg = ('Option "--external-runner-testdir" requires '741 '"--external-runner-chdir=test".')742 raise LoaderError(msg)743 return test.ExternalRunnerSpec(runner, chdir, test_dir)744 elif chdir:745 msg = ('Option "--external-runner-chdir" requires '746 '"--external-runner" to be set.')747 raise LoaderError(msg)748 elif test_dir:749 msg = ('Option "--external-runner-testdir" requires '750 '"--external-runner" to be set.')751 raise LoaderError(msg)752 return None # Skip external runner753 def discover(self, reference, which_tests=DiscoverMode.DEFAULT):754 """755 :param reference: arguments passed to the external_runner756 :param which_tests: Limit tests to be displayed757 :type which_tests: :class:`DiscoverMode`758 :return: list of matching tests759 """760 if (not self._external_runner) or (reference is None):761 return []762 return [(test.ExternalRunnerTest, {'name': reference, 'external_runner':763 self._external_runner,764 'external_runner_argument':765 reference})]766 @staticmethod767 def get_type_label_mapping():768 return {test.ExternalRunnerTest: 'EXTERNAL'}769 @staticmethod770 def get_decorator_mapping():771 return {test.ExternalRunnerTest: output.TERM_SUPPORT.healthy_str}772class TapLoader(SimpleFileLoader):773 """774 Test Anything Protocol loader class775 """776 name = "tap"777 @staticmethod778 def get_type_label_mapping():779 mapping = SimpleFileLoader.get_type_label_mapping()780 mapping.update(781 {test.TapTest: 'TAP'})782 return mapping783 @staticmethod784 def get_decorator_mapping():785 mapping = SimpleFileLoader.get_decorator_mapping()786 mapping.update(787 {test.TapTest: output.TERM_SUPPORT.healthy_str})788 return mapping789 def _make_simple_test(self, test_path, subtests_filter):790 return self._make_test(test.TapTest, test_path,791 subtests_filter=subtests_filter,792 executable=test_path)793loader = TestLoaderProxy()

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run avocado automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful