def __init__(self, yaml_test, settings, filename, title): self.settings = settings self.filename = filename self.name = yaml_test.get('name', title) self.engine = yaml_test.get('engine', 'engine.py:ExecutionEngine') self.description = yaml_test.get('description') self.preconditions = yaml_test.get('preconditions', {}) self.tags = yaml_test.get('tags') self.features = yaml_test.get('features') self.scenario = Scenario(yaml_test.get('scenario', []), underscore_case_steps=self.settings.get("underscore case steps", False)) if re.compile("^(.*?)\:(.*?)$").match(self.engine) is None: raise RuntimeError("ERROR : engine should be of the form 'engine_filename.py:ClassName'") else: module_source = path.abspath(path.join(self.settings['engine_folder'], self.engine.split(":")[0])) if not path.exists(module_source): raise RuntimeError("ERROR : engine filename '{}' not found.".format(self.engine.split(':')[0])) engine_class_name = self.engine.split(":")[1] engine_module = imp.load_source("engine", module_source) if len([x for x in inspect.getmembers(engine_module) if x[0] == engine_class_name]) == 0: raise RuntimeError("ERROR : Class {} not found in engine.".format(engine_class_name)) self.engine_class = [x for x in inspect.getmembers(engine_module) if x[0] == engine_class_name][0][1] if self.name[0].isdigit(): raise RuntimeError("ERROR : Test names cannot start with a digit.") if "test" in self.name.lower(): warn("WARNING: The word 'test' should not appear in your test name - it is redundant.\n")
class Test(object): def __init__(self, yaml_test, settings, filename, title): self.settings = settings self.filename = filename self.name = yaml_test.get('name', title) self.engine = yaml_test.get('engine', 'engine.py:ExecutionEngine') self.description = yaml_test.get('description') self.preconditions = yaml_test.get('preconditions', {}) self.tags = yaml_test.get('tags') self.features = yaml_test.get('features') self.scenario = Scenario(yaml_test.get('scenario', []), underscore_case_steps=self.settings.get("underscore case steps", False)) if re.compile("^(.*?)\:(.*?)$").match(self.engine) is None: raise RuntimeError("ERROR : engine should be of the form 'engine_filename.py:ClassName'") else: module_source = path.abspath(path.join(self.settings['engine_folder'], self.engine.split(":")[0])) if not path.exists(module_source): raise RuntimeError("ERROR : engine filename '{}' not found.".format(self.engine.split(':')[0])) engine_class_name = self.engine.split(":")[1] engine_module = imp.load_source("engine", module_source) if len([x for x in inspect.getmembers(engine_module) if x[0] == engine_class_name]) == 0: raise RuntimeError("ERROR : Class {} not found in engine.".format(engine_class_name)) self.engine_class = [x for x in inspect.getmembers(engine_module) if x[0] == engine_class_name][0][1] if self.name[0].isdigit(): raise RuntimeError("ERROR : Test names cannot start with a digit.") if "test" in self.name.lower(): warn("WARNING: The word 'test' should not appear in your test name - it is redundant.\n") def to_dict(self): return { "filename": self.filename, "name": self.name, "engine": self.engine, "preconditions": self.preconditions, "description": self.description, "tags": self.tags, "features": self.features, "scenario": self.scenario.to_dict(), } def run(self): start_time = time.time() stacktrace = None engine = None failure = False show_hitch_stacktrace = self.settings.get("show_hitch_stacktrace", False) try: engine = self.engine_class(self.settings, self.preconditions) engine.name = self.name engine.aborted = False engine.stacktrace = None engine._test = self except Exception as e: stacktrace = HitchStacktrace(self, TestPosition.SETUP, show_hitch_stacktrace) failure = True if not failure: log("RUNNING TEST {}\n".format(self.name)) try: verify(self.settings.get("environment", [])) engine.set_up() except Exception as e: stacktrace = HitchStacktrace(self, TestPosition.SETUP, show_hitch_stacktrace) failure = True if not failure: for step in self.scenario.steps: try: step.run(engine) except Exception as e: stacktrace = HitchStacktrace(self, TestPosition.STEP, show_hitch_stacktrace, step=step) failure = True break if not engine.aborted: if failure: try: engine.stacktrace = stacktrace engine.on_failure() except Exception as e: stacktrace = HitchStacktrace(self, TestPosition.ON_FAILURE, show_hitch_stacktrace) else: try: engine.on_success() except Exception as e: failure = True stacktrace = HitchStacktrace(self, TestPosition.ON_SUCCESS, show_hitch_stacktrace) try: engine.tear_down() except Exception as e: failure = True stacktrace = HitchStacktrace(self, TestPosition.TEARDOWN, show_hitch_stacktrace) duration = time.time() - start_time dict_stacktrace = stacktrace.to_dict() if stacktrace is not None else None aborted = engine.aborted if engine is not None else False result = Result(self, failure, duration, stacktrace=dict_stacktrace, aborted=aborted) return result