diff --git a/src/_balder/controllers/device_controller.py b/src/_balder/controllers/device_controller.py index 4c4a403a..a6db4467 100644 --- a/src/_balder/controllers/device_controller.py +++ b/src/_balder/controllers/device_controller.py @@ -1,4 +1,6 @@ from __future__ import annotations + +import copy from typing import Dict, List, Type, Union, TYPE_CHECKING import sys @@ -443,10 +445,15 @@ def resolve_mapped_vdevice_strings(self): if all_instanced_features is None: # has no features -> skip return - for _, cur_feature in all_instanced_features.items(): - if cur_feature.active_vdevices != {}: + for cur_attr_name, cur_feature in all_instanced_features.items(): + # clone feature and its active_device dict to make sure that shared instances in parent classes are handled + # correctly + new_feature = copy.copy(cur_feature) + new_feature.active_vdevices = {**cur_feature.active_vdevices} + setattr(self.related_cls, cur_attr_name, new_feature) + if new_feature.active_vdevices != {}: # do something only if there exists an internal mapping - for cur_mapped_vdevice, cur_mapped_device in cur_feature.active_vdevices.items(): + for cur_mapped_vdevice, cur_mapped_device in new_feature.active_vdevices.items(): if isinstance(cur_mapped_device, str): resolved_device = \ scenario_or_setup_controller.get_inner_device_class_by_string(cur_mapped_device) @@ -454,5 +461,5 @@ def resolve_mapped_vdevice_strings(self): raise RuntimeError( f"found no possible matching name while trying to resolve " f"the given vDevice string `{cur_mapped_vdevice}` in feature " - f"`{cur_feature.__class__.__name__}`") - cur_feature.active_vdevices[cur_mapped_vdevice] = resolved_device + f"`{new_feature.__class__.__name__}`") + new_feature.active_vdevices[cur_mapped_vdevice] = resolved_device diff --git a/src/_balder/executor/variation_executor.py b/src/_balder/executor/variation_executor.py index e673fb91..30f690e9 100644 --- a/src/_balder/executor/variation_executor.py +++ b/src/_balder/executor/variation_executor.py @@ -391,9 +391,9 @@ class and sets this information to the property `_feature_replacement`. In addit cur_setup_features = DeviceController.get_for(cur_setup_device).get_all_instantiated_feature_objects() all_assigned_setup_features = [] - cur_scenario_device_orig_features = \ - DeviceController.get_for(cur_scenario_device).get_original_instanced_feature_objects() - for cur_attr_name, cur_scenario_feature_obj in cur_scenario_device_orig_features.items(): + cur_scenario_device_features = \ + DeviceController.get_for(cur_scenario_device).get_all_instantiated_feature_objects() + for cur_attr_name, cur_scenario_feature_obj in cur_scenario_device_features.items(): active_scenario_vdevice, mapped_scenario_device = cur_scenario_feature_obj.active_vdevice_device_mapping cur_setup_feature_objs = self._get_matching_setup_features_for( @@ -677,7 +677,7 @@ def update_vdevice_referenced_feature_instances(self): cur_vdevice, cur_device = cur_feature.active_vdevice_device_mapping if cur_vdevice is not None and cur_device is not None: cur_vdevice_controller = VDeviceController.get_for(cur_vdevice) - cur_vdevice_all_features = cur_vdevice_controller.get_original_instanced_feature_objects() + cur_vdevice_all_features = cur_vdevice_controller.get_all_instantiated_feature_objects() cur_device_controller = DeviceController.get_for(cur_device) cur_device_all_features = cur_device_controller.get_all_instantiated_feature_objects() diff --git a/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/__init__.py b/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/__init__.py b/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/balderglob.py b/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/balderglob.py new file mode 100644 index 00000000..232be40a --- /dev/null +++ b/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/balderglob.py @@ -0,0 +1,150 @@ +from typing import Literal, Union, List +from datetime import datetime + +import pathlib +import balder +import argparse +import logging +from multiprocessing import Queue +from .lib.utils import FixtureReturn + +logger = logging.getLogger(__file__) + + +class MyTestException(Exception): + pass + + +class RuntimeObserver: + """This is a helper object, that will be used from this test environment to observe the execution order""" + queue: Union[Queue, None] = None + + error_throwing = {} + + @staticmethod + def add_entry(file: Union[str, pathlib.Path], cls: object, meth: callable, msg: str, + category: Literal["fixture", "testcase", "feature"] = None, + part: Literal["construction", "teardown"] = None): + """ + adds a new entry and sends it over the queue + + :param file: the full filepath where the log will be generated + + :param cls: the class object, the entry is generated in + + :param meth: the method name, the entry is generated in + + :param msg: the message that should be inserted into the entry + + :param category: optional string of the category the entry is from + + :param part: optional string of the sub part the entry is from + """ + if hasattr(meth, 'fn'): + meth = meth.fn + new_dataset = { + "timestamp": datetime.now(), "file": file, "cls": "" if cls is None else cls.__name__, + "meth": meth.__name__, "msg": msg, "category": category, "part": part + } + logger.info("{:22} | {:20} | {:30} | {:12} | {:15} | {}".format( + pathlib.Path(file).parts[-1], "" if cls is None else cls.__name__, "" if meth is None else meth.__name__, + "" if category is None else category, "" if part is None else part, "" if msg is None else msg)) + + RuntimeObserver.queue.put(new_dataset) + # check if we have to throw the error + error_throwing_required = len(RuntimeObserver.error_throwing) > 0 + for cur_key in RuntimeObserver.error_throwing.keys(): + new_dataset_val = new_dataset[cur_key] + if callable(new_dataset_val): + new_dataset_val = new_dataset_val.__name__ + if new_dataset_val != RuntimeObserver.error_throwing[cur_key]: + error_throwing_required = False + break + if error_throwing_required: + raise MyTestException(f'raise test triggered exception for `{str(RuntimeObserver.error_throwing)}`') + + +class MyErrorThrowingPlugin(balder.BalderPlugin): + """ + This is a plugin that reads the values from console arguments and sets these values into the + :class:`RuntimeObserver`. The static method `RuntimeObserver.add_entry` will automatically throw an exception on the + given position. + """ + + def addoption(self, argument_parser: argparse.ArgumentParser): + argument_parser.add_argument('--test-error-file', help='the file id, the error should be thrown in') + argument_parser.add_argument('--test-error-cls', help='the class id, the error should be thrown in') + argument_parser.add_argument('--test-error-meth', help='the meth id, the error should be thrown in') + argument_parser.add_argument('--test-error-part', help='the part (`construct` or `teardown`), the error should ' + 'be thrown in - only for fixtures') + + def modify_collected_pyfiles(self, pyfiles: List[pathlib.Path]) -> List[pathlib.Path]: + # use this method to set the values + RuntimeObserver.error_throwing = {} + if self.balder_session.parsed_args.test_error_file: + path = pathlib.Path(self.balder_session.parsed_args.test_error_file) + if not path.is_absolute(): + path = str(self.balder_session.working_dir.joinpath(path)) + RuntimeObserver.error_throwing['file'] = path + if self.balder_session.parsed_args.test_error_cls: + RuntimeObserver.error_throwing['cls'] = self.balder_session.parsed_args.test_error_cls + if self.balder_session.parsed_args.test_error_meth: + RuntimeObserver.error_throwing['meth'] = self.balder_session.parsed_args.test_error_meth + if self.balder_session.parsed_args.test_error_part: + RuntimeObserver.error_throwing['part'] = self.balder_session.parsed_args.test_error_part + return pyfiles + + +@balder.fixture(level="session") +def balderglob_fixture_session(): + RuntimeObserver.add_entry(__file__, None, balderglob_fixture_session, "begin execution CONSTRUCTION of fixture", + category="fixture", part="construction") + + yield FixtureReturn.BALDERGLOB_SESSION + + RuntimeObserver.add_entry(__file__, None, balderglob_fixture_session, "begin execution TEARDOWN of fixture", + category="fixture", part="teardown") + + +@balder.fixture(level="setup") +def balderglob_fixture_setup(): + RuntimeObserver.add_entry(__file__, None, balderglob_fixture_setup, "begin execution CONSTRUCTION of fixture", + category="fixture", part="construction") + + yield FixtureReturn.BALDERGLOB_SETUP + + RuntimeObserver.add_entry(__file__, None, balderglob_fixture_setup, "begin execution TEARDOWN of fixture", + category="fixture", part="teardown") + + +@balder.fixture(level="scenario") +def balderglob_fixture_scenario(): + RuntimeObserver.add_entry(__file__, None, balderglob_fixture_scenario, "begin execution CONSTRUCTION of fixture", + category="fixture", part="construction") + + yield FixtureReturn.BALDERGLOB_SCENARIO + + RuntimeObserver.add_entry(__file__, None, balderglob_fixture_scenario, "begin execution TEARDOWN of fixture", + category="fixture", part="teardown") + + +@balder.fixture(level="variation") +def balderglob_fixture_variation(): + RuntimeObserver.add_entry(__file__, None, balderglob_fixture_variation, "begin execution CONSTRUCTION of fixture", + category="fixture", part="construction") + + yield FixtureReturn.BALDERGLOB_VARIATION + + RuntimeObserver.add_entry(__file__, None, balderglob_fixture_variation, "begin execution TEARDOWN of fixture", + category="fixture", part="teardown") + + +@balder.fixture(level="testcase") +def balderglob_fixture_testcase(): + RuntimeObserver.add_entry(__file__, None, balderglob_fixture_testcase, "begin execution CONSTRUCTION of fixture", + category="fixture", part="construction") + + yield FixtureReturn.BALDERGLOB_TESTCASE + + RuntimeObserver.add_entry(__file__, None, balderglob_fixture_testcase, "begin execution TEARDOWN of fixture", + category="fixture", part="teardown") diff --git a/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/lib/__init__.py b/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/lib/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/lib/connections.py b/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/lib/connections.py new file mode 100644 index 00000000..cf1e8b61 --- /dev/null +++ b/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/lib/connections.py @@ -0,0 +1,11 @@ +import balder + + +@balder.insert_into_tree() +class AConnection(balder.Connection): + pass + + +@balder.insert_into_tree() +class BConnection(balder.Connection): + pass diff --git a/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/lib/features.py b/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/lib/features.py new file mode 100644 index 00000000..ef6e84bf --- /dev/null +++ b/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/lib/features.py @@ -0,0 +1,49 @@ +import balder +from ..balderglob import RuntimeObserver + + +class FeatureI(balder.Feature): + + def do_something(self): + RuntimeObserver.add_entry( + __file__, FeatureI, FeatureI.do_something, "enter `FeatureI.do_something`", category="feature") + + +class FeatureIOverwritten(FeatureI): + + def do_something(self): + RuntimeObserver.add_entry( + __file__, FeatureIOverwritten, FeatureIOverwritten.do_something, "enter `FeatureIChild.do_something`", + category="feature") + + +class FeatureII(balder.Feature): + + class Dev1(balder.VDevice): + feat = FeatureI() + + def do_something(self): + RuntimeObserver.add_entry( + __file__, FeatureII, FeatureII.do_something, "enter `FeatureII.do_something`", category="feature") + + +class NewlyDefinedFeature(balder.Feature): + """this feature will be instantiated in `ScenarioAChild` (and not in `ScenarioAParent`)""" + def do_something(self): + RuntimeObserver.add_entry( + __file__, NewlyDefinedFeature, NewlyDefinedFeature.do_something, "enter `NewlyDefinedFeature.do_something`", + category="feature") + + +class FeatureIII(balder.Feature): + + def do_something(self): + RuntimeObserver.add_entry( + __file__, FeatureIII, FeatureIII.do_something, "enter `FeatureIII.do_something`", category="feature") + + +class FeatureIV(balder.Feature): + + def do_something(self): + RuntimeObserver.add_entry( + __file__, FeatureIV, FeatureIV.do_something, "enter `FeatureIV.do_something`", category="feature") diff --git a/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/lib/utils.py b/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/lib/utils.py new file mode 100644 index 00000000..fe4559af --- /dev/null +++ b/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/lib/utils.py @@ -0,0 +1,22 @@ + + +class FixtureReturn: + """helper const class for return values""" + BALDERGLOB_SESSION = "balderglob_session_fixt" + BALDERGLOB_SETUP = "balderglob_setup_fixt" + BALDERGLOB_SCENARIO = "balderglob_scenario_fixt" + BALDERGLOB_VARIATION = "balderglob_variation_fixt" + BALDERGLOB_TESTCASE = "balderglob_testcase_fixt" + + SETUP_SESSION = "setup_session_fixt" + SETUP_SETUP = "setup_setup_fixt" + SETUP_SCENARIO = "setup_scenario_fixt" + SETUP_VARIATION = "setup_variation_fixt" + SETUP_TESTCASE = "setup_testcase_fixt" + + SCENARIO_SESSION = "scenario_session_fixt" + SCENARIO_SETUP = "scenario_setup_fixt" + SCENARIO_SCENARIO = "scenario_scenario_fixt" + SCENARIO_VARIATION = "scenario_variation_fixt" + SCENARIO_TESTCASE = "scenario_testcase_fixt" + diff --git a/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/scenarios/__init__.py b/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/scenarios/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/scenarios/scenario_a_child1.py b/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/scenarios/scenario_a_child1.py new file mode 100644 index 00000000..d4694409 --- /dev/null +++ b/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/scenarios/scenario_a_child1.py @@ -0,0 +1,121 @@ +import balder +import logging +from ..lib.features import FeatureIOverwritten, FeatureII, NewlyDefinedFeature +from ..lib.connections import AConnection +from ..balderglob import RuntimeObserver +from .scenario_a_parent import ScenarioAParent + +logger = logging.getLogger(__file__) + + +class ScenarioAChild1(ScenarioAParent): + """This is the CHILD scenario of category A""" + + class ScenarioDevice1(ScenarioAParent.ScenarioDevice1): + i = FeatureIOverwritten() + + @balder.connect(ScenarioDevice1, over_connection=AConnection) + class ScenarioDevice2(ScenarioAParent.ScenarioDevice2): + new = NewlyDefinedFeature() + + def test_a_1(self): + RuntimeObserver.add_entry(__file__, ScenarioAChild1, ScenarioAChild1.test_a_1, category="testcase", + msg=f"execute Test `{ScenarioAChild1.test_a_1.__qualname__}`") + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + self.ScenarioDevice2.new.do_something() + + def test_a_2(self): + RuntimeObserver.add_entry(__file__, ScenarioAChild1, ScenarioAChild1.test_a_2, category="testcase", + msg=f"execute Test `{ScenarioAChild1.test_a_2.__qualname__}`") + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + self.ScenarioDevice2.new.do_something() + + @balder.fixture(level="session") + def fixture_session(self): + RuntimeObserver.add_entry(__file__, ScenarioAChild1, ScenarioAChild1.fixture_session, category="fixture", + part="construction", msg="begin execution CONSTRUCTION of fixture") + + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + self.ScenarioDevice2.new.do_something() + + yield + + RuntimeObserver.add_entry(__file__, ScenarioAChild1, ScenarioAChild1.fixture_session, category="fixture", + part="teardown", msg="begin execution TEARDOWN of fixture") + + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + self.ScenarioDevice2.new.do_something() + + @balder.fixture(level="setup") + def fixture_setup(self): + RuntimeObserver.add_entry(__file__, ScenarioAChild1, ScenarioAChild1.fixture_setup, category="fixture", + part="construction", msg="begin execution CONSTRUCTION of fixture") + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + self.ScenarioDevice2.new.do_something() + + yield + + RuntimeObserver.add_entry(__file__, ScenarioAChild1, ScenarioAChild1.fixture_setup, category="fixture", + part="teardown", msg="begin execution TEARDOWN of fixture") + + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + self.ScenarioDevice2.new.do_something() + + @balder.fixture(level="scenario") + def fixture_scenario(self): + RuntimeObserver.add_entry(__file__, ScenarioAChild1, ScenarioAChild1.fixture_scenario, category="fixture", + part="construction", msg="begin execution CONSTRUCTION of fixture") + + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + self.ScenarioDevice2.new.do_something() + + yield + + RuntimeObserver.add_entry(__file__, ScenarioAChild1, ScenarioAChild1.fixture_scenario, category="fixture", + part="teardown", msg="begin execution TEARDOWN of fixture") + + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + self.ScenarioDevice2.new.do_something() + + @balder.fixture(level="variation") + def fixture_variation(self): + RuntimeObserver.add_entry(__file__, ScenarioAChild1, ScenarioAChild1.fixture_variation, category="fixture", + part="construction", msg="begin execution CONSTRUCTION of fixture") + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + self.ScenarioDevice2.new.do_something() + + yield + + RuntimeObserver.add_entry(__file__, ScenarioAChild1, ScenarioAChild1.fixture_variation, category="fixture", + part="teardown", msg="begin execution TEARDOWN of fixture") + + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + self.ScenarioDevice2.new.do_something() + + @balder.fixture(level="testcase") + def fixture_testcase(self): + RuntimeObserver.add_entry(__file__, ScenarioAChild1, ScenarioAChild1.fixture_testcase, category="fixture", + part="construction", msg="begin execution CONSTRUCTION of fixture") + + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + self.ScenarioDevice2.new.do_something() + + yield + + RuntimeObserver.add_entry(__file__, ScenarioAChild1, ScenarioAChild1.fixture_testcase, category="fixture", + part="teardown", msg="begin execution TEARDOWN of fixture") + + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + self.ScenarioDevice2.new.do_something() diff --git a/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/scenarios/scenario_a_child2.py b/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/scenarios/scenario_a_child2.py new file mode 100644 index 00000000..eea00016 --- /dev/null +++ b/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/scenarios/scenario_a_child2.py @@ -0,0 +1,121 @@ +import balder +import logging +from ..lib.features import FeatureIOverwritten, FeatureII, NewlyDefinedFeature +from ..lib.connections import AConnection +from ..balderglob import RuntimeObserver +from .scenario_a_parent import ScenarioAParent + +logger = logging.getLogger(__file__) + + +class ScenarioAChild2(ScenarioAParent): + """This is the CHILD scenario of category A""" + + class ScenarioDevice1(ScenarioAParent.ScenarioDevice1): + i = FeatureIOverwritten() + + @balder.connect(ScenarioDevice1, over_connection=AConnection) + class ScenarioDevice2(ScenarioAParent.ScenarioDevice2): + new = NewlyDefinedFeature() + + def test_a_1(self): + RuntimeObserver.add_entry(__file__, ScenarioAChild2, ScenarioAChild2.test_a_1, category="testcase", + msg=f"execute Test `{ScenarioAChild2.test_a_1.__qualname__}`") + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + self.ScenarioDevice2.new.do_something() + + def test_a_2(self): + RuntimeObserver.add_entry(__file__, ScenarioAChild2, ScenarioAChild2.test_a_2, category="testcase", + msg=f"execute Test `{ScenarioAChild2.test_a_2.__qualname__}`") + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + self.ScenarioDevice2.new.do_something() + + @balder.fixture(level="session") + def fixture_session(self): + RuntimeObserver.add_entry(__file__, ScenarioAChild2, ScenarioAChild2.fixture_session, category="fixture", + part="construction", msg="begin execution CONSTRUCTION of fixture") + + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + self.ScenarioDevice2.new.do_something() + + yield + + RuntimeObserver.add_entry(__file__, ScenarioAChild2, ScenarioAChild2.fixture_session, category="fixture", + part="teardown", msg="begin execution TEARDOWN of fixture") + + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + self.ScenarioDevice2.new.do_something() + + @balder.fixture(level="setup") + def fixture_setup(self): + RuntimeObserver.add_entry(__file__, ScenarioAChild2, ScenarioAChild2.fixture_setup, category="fixture", + part="construction", msg="begin execution CONSTRUCTION of fixture") + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + self.ScenarioDevice2.new.do_something() + + yield + + RuntimeObserver.add_entry(__file__, ScenarioAChild2, ScenarioAChild2.fixture_setup, category="fixture", + part="teardown", msg="begin execution TEARDOWN of fixture") + + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + self.ScenarioDevice2.new.do_something() + + @balder.fixture(level="scenario") + def fixture_scenario(self): + RuntimeObserver.add_entry(__file__, ScenarioAChild2, ScenarioAChild2.fixture_scenario, category="fixture", + part="construction", msg="begin execution CONSTRUCTION of fixture") + + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + self.ScenarioDevice2.new.do_something() + + yield + + RuntimeObserver.add_entry(__file__, ScenarioAChild2, ScenarioAChild2.fixture_scenario, category="fixture", + part="teardown", msg="begin execution TEARDOWN of fixture") + + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + self.ScenarioDevice2.new.do_something() + + @balder.fixture(level="variation") + def fixture_variation(self): + RuntimeObserver.add_entry(__file__, ScenarioAChild2, ScenarioAChild2.fixture_variation, category="fixture", + part="construction", msg="begin execution CONSTRUCTION of fixture") + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + self.ScenarioDevice2.new.do_something() + + yield + + RuntimeObserver.add_entry(__file__, ScenarioAChild2, ScenarioAChild2.fixture_variation, category="fixture", + part="teardown", msg="begin execution TEARDOWN of fixture") + + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + self.ScenarioDevice2.new.do_something() + + @balder.fixture(level="testcase") + def fixture_testcase(self): + RuntimeObserver.add_entry(__file__, ScenarioAChild2, ScenarioAChild2.fixture_testcase, category="fixture", + part="construction", msg="begin execution CONSTRUCTION of fixture") + + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + self.ScenarioDevice2.new.do_something() + + yield + + RuntimeObserver.add_entry(__file__, ScenarioAChild2, ScenarioAChild2.fixture_testcase, category="fixture", + part="teardown", msg="begin execution TEARDOWN of fixture") + + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + self.ScenarioDevice2.new.do_something() diff --git a/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/scenarios/scenario_a_parent.py b/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/scenarios/scenario_a_parent.py new file mode 100644 index 00000000..301fc639 --- /dev/null +++ b/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/scenarios/scenario_a_parent.py @@ -0,0 +1,109 @@ +import balder +import logging +from ..lib.features import FeatureI, FeatureII +from ..lib.connections import AConnection +from ..balderglob import RuntimeObserver + +logger = logging.getLogger(__file__) + + +class ScenarioAParent(balder.Scenario): + """This is the PARENT scenario of category A""" + + class ScenarioDevice1(balder.Device): + i = FeatureI() + + @balder.connect(ScenarioDevice1, over_connection=AConnection) + class ScenarioDevice2(balder.Device): + ii = FeatureII(Dev1="ScenarioDevice1") + # the newly-feature is not defined here + + def test_a_1(self): + RuntimeObserver.add_entry(__file__, ScenarioAParent, ScenarioAParent.test_a_1, category="testcase", + msg=f"execute Test `{ScenarioAParent.test_a_1.__qualname__}`") + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + + def test_a_2(self): + RuntimeObserver.add_entry(__file__, ScenarioAParent, ScenarioAParent.test_a_2, category="testcase", + msg=f"execute Test `{ScenarioAParent.test_a_2.__qualname__}`") + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + + @balder.fixture(level="session") + def fixture_session(self): + RuntimeObserver.add_entry(__file__, ScenarioAParent, ScenarioAParent.fixture_session, category="fixture", + part="construction", msg="begin execution CONSTRUCTION of fixture") + + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + + yield + + RuntimeObserver.add_entry(__file__, ScenarioAParent, ScenarioAParent.fixture_session, category="fixture", + part="teardown", msg="begin execution TEARDOWN of fixture") + + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + + @balder.fixture(level="setup") + def fixture_setup(self): + RuntimeObserver.add_entry(__file__, ScenarioAParent, ScenarioAParent.fixture_setup, category="fixture", + part="construction", msg="begin execution CONSTRUCTION of fixture") + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + + yield + + RuntimeObserver.add_entry(__file__, ScenarioAParent, ScenarioAParent.fixture_setup, category="fixture", + part="teardown", msg="begin execution TEARDOWN of fixture") + + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + + @balder.fixture(level="scenario") + def fixture_scenario(self): + RuntimeObserver.add_entry(__file__, ScenarioAParent, ScenarioAParent.fixture_scenario, category="fixture", + part="construction", msg="begin execution CONSTRUCTION of fixture") + + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + + yield + + RuntimeObserver.add_entry(__file__, ScenarioAParent, ScenarioAParent.fixture_scenario, category="fixture", + part="teardown", msg="begin execution TEARDOWN of fixture") + + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + + @balder.fixture(level="variation") + def fixture_variation(self): + RuntimeObserver.add_entry(__file__, ScenarioAParent, ScenarioAParent.fixture_variation, category="fixture", + part="construction", msg="begin execution CONSTRUCTION of fixture") + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + + yield + + RuntimeObserver.add_entry(__file__, ScenarioAParent, ScenarioAParent.fixture_variation, category="fixture", + part="teardown", msg="begin execution TEARDOWN of fixture") + + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + + @balder.fixture(level="testcase") + def fixture_testcase(self): + RuntimeObserver.add_entry(__file__, ScenarioAParent, ScenarioAParent.fixture_testcase, category="fixture", + part="construction", msg="begin execution CONSTRUCTION of fixture") + + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + + yield + + RuntimeObserver.add_entry(__file__, ScenarioAParent, ScenarioAParent.fixture_testcase, category="fixture", + part="teardown", msg="begin execution TEARDOWN of fixture") + + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() diff --git a/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/setups/__init__.py b/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/setups/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/setups/setup_a.py b/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/setups/setup_a.py new file mode 100644 index 00000000..a19cd19a --- /dev/null +++ b/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/setups/setup_a.py @@ -0,0 +1,109 @@ +import balder +import logging +from .setup_features import SetupFeatureI, SetupFeatureII, NewlySetupFeature +from ..lib.connections import AConnection +from ..balderglob import RuntimeObserver + +logger = logging.getLogger(__name__) + + +class SetupA(balder.Setup): + """This is a setup of category A (exactly the same as scenario A)""" + + class SetupDevice1(balder.Device): + s_i = SetupFeatureI() + + @balder.connect(SetupDevice1, over_connection=AConnection) + class SetupDevice2(balder.Device): + s_ii = SetupFeatureII() + s_new = NewlySetupFeature() + + @balder.fixture(level="session") + def fixture_session(self): + RuntimeObserver.add_entry(__file__, SetupA, SetupA.fixture_session, category="fixture", part="construction", + msg="begin execution CONSTRUCTION of fixture") + + self.SetupDevice1.s_i.do_something() + self.SetupDevice2.s_ii.do_something() + self.SetupDevice2.s_new.do_something() + + yield + + RuntimeObserver.add_entry(__file__, SetupA, SetupA.fixture_session, category="fixture", part="teardown", + msg="begin execution TEARDOWN of fixture") + + self.SetupDevice1.s_i.do_something() + self.SetupDevice2.s_ii.do_something() + self.SetupDevice2.s_new.do_something() + + @balder.fixture(level="setup") + def fixture_setup(self): + RuntimeObserver.add_entry(__file__, SetupA, SetupA.fixture_setup, category="fixture", part="construction", + msg="begin execution CONSTRUCTION of fixture") + + self.SetupDevice1.s_i.do_something() + self.SetupDevice2.s_ii.do_something() + self.SetupDevice2.s_new.do_something() + + yield + + RuntimeObserver.add_entry(__file__, SetupA, SetupA.fixture_setup, category="fixture", part="teardown", + msg="begin execution TEARDOWN of fixture") + + self.SetupDevice1.s_i.do_something() + self.SetupDevice2.s_ii.do_something() + self.SetupDevice2.s_new.do_something() + + @balder.fixture(level="scenario") + def fixture_scenario(self): + RuntimeObserver.add_entry(__file__, SetupA, SetupA.fixture_scenario, category="fixture", part="construction", + msg="begin execution CONSTRUCTION of fixture") + + self.SetupDevice1.s_i.do_something() + self.SetupDevice2.s_ii.do_something() + self.SetupDevice2.s_new.do_something() + + yield + + RuntimeObserver.add_entry(__file__, SetupA, SetupA.fixture_scenario, category="fixture", part="teardown", + msg="begin execution TEARDOWN of fixture") + + self.SetupDevice1.s_i.do_something() + self.SetupDevice2.s_ii.do_something() + self.SetupDevice2.s_new.do_something() + + @balder.fixture(level="variation") + def fixture_variation(self): + RuntimeObserver.add_entry(__file__, SetupA, SetupA.fixture_variation, category="fixture", part="construction", + msg="begin execution CONSTRUCTION of fixture") + + self.SetupDevice1.s_i.do_something() + self.SetupDevice2.s_ii.do_something() + self.SetupDevice2.s_new.do_something() + + yield + + RuntimeObserver.add_entry(__file__, SetupA, SetupA.fixture_variation, category="fixture", part="teardown", + msg="begin execution TEARDOWN of fixture") + + self.SetupDevice1.s_i.do_something() + self.SetupDevice2.s_ii.do_something() + self.SetupDevice2.s_new.do_something() + + @balder.fixture(level="testcase") + def fixture_testcase(self): + RuntimeObserver.add_entry(__file__, SetupA, SetupA.fixture_testcase, category="fixture", part="construction", + msg="begin execution CONSTRUCTION of fixture") + + self.SetupDevice1.s_i.do_something() + self.SetupDevice2.s_ii.do_something() + self.SetupDevice2.s_new.do_something() + + yield + + RuntimeObserver.add_entry(__file__, SetupA, SetupA.fixture_testcase, category="fixture", part="teardown", + msg="begin execution TEARDOWN of fixture") + + self.SetupDevice1.s_i.do_something() + self.SetupDevice2.s_ii.do_something() + self.SetupDevice2.s_new.do_something() diff --git a/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/setups/setup_features/__init__.py b/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/setups/setup_features/__init__.py new file mode 100644 index 00000000..8925ccf6 --- /dev/null +++ b/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/setups/setup_features/__init__.py @@ -0,0 +1,9 @@ +from .feature_i import SetupFeatureI +from .feature_ii import SetupFeatureII +from .newly_setup_feature import NewlySetupFeature + +__all__ = [ + "SetupFeatureI", + "SetupFeatureII", + "NewlySetupFeature" +] diff --git a/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/setups/setup_features/feature_i.py b/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/setups/setup_features/feature_i.py new file mode 100644 index 00000000..a40b0a04 --- /dev/null +++ b/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/setups/setup_features/feature_i.py @@ -0,0 +1,10 @@ +from ...lib.features import FeatureIOverwritten +from ...balderglob import RuntimeObserver + + +class SetupFeatureI(FeatureIOverwritten): + + def do_something(self): + RuntimeObserver.add_entry( + __file__, SetupFeatureI, SetupFeatureI.do_something, "enter `SetupFeatureI.do_something`", + category="feature") diff --git a/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/setups/setup_features/feature_ii.py b/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/setups/setup_features/feature_ii.py new file mode 100644 index 00000000..a38e27c7 --- /dev/null +++ b/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/setups/setup_features/feature_ii.py @@ -0,0 +1,10 @@ +from ...lib.features import FeatureII +from ...balderglob import RuntimeObserver + + +class SetupFeatureII(FeatureII): + + def do_something(self): + RuntimeObserver.add_entry( + __file__, SetupFeatureII, SetupFeatureII.do_something, "enter `SetupFeatureII.do_something`", + category="feature") diff --git a/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/setups/setup_features/newly_setup_feature.py b/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/setups/setup_features/newly_setup_feature.py new file mode 100644 index 00000000..75fb6776 --- /dev/null +++ b/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/env/setups/setup_features/newly_setup_feature.py @@ -0,0 +1,10 @@ +from ...lib.features import NewlyDefinedFeature +from ...balderglob import RuntimeObserver + + +class NewlySetupFeature(NewlyDefinedFeature): + + def do_something(self): + RuntimeObserver.add_entry( + __file__, NewlySetupFeature, NewlySetupFeature.do_something, "enter `NewlySetupFeature.do_something`", + category="feature") diff --git a/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining.py b/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining.py new file mode 100644 index 00000000..c333528f --- /dev/null +++ b/tests/scenario_inheritance/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining/test_0_scenario_correctly_overwrite_and_add_feature_without_redefining.py @@ -0,0 +1,388 @@ +from _balder.testresult import ResultState +from _balder.balder_session import BalderSession + +from tests.test_utilities.base_0_envtester_class import Base0EnvtesterClass + + +class Test0ScenarioDeviceCorrectlyOverwriteAndAddFeatureWithoutRedefining(Base0EnvtesterClass): + """ + This testcase executes the basic envtester environment but uses an inherited scenario `ScenarioAChild1`. Within this + scenario we define an additional feature class that was not known in parent scenario `ScenarioAParent`. In addition + to that, the environment overwrites an existing feature within the `ScenarioAChild1`-Device that is a child class of + the overwritten one. It will not redefine the feature `ii = FeatureII()` of `ScenarioDevice2`. This FeatureII also + defines a VDev relation to `Device1`. It defines two child scenarios and it will be expected that both are executed. + + The test secures that it can be executed correctly and without an error. + """ + + @property + def expected_data(self) -> tuple: + return ( + # FIXTURE-CONSTRUCTION: balderglob_fixture_session + {"file": "balderglob.py", "meth": "balderglob_fixture_session", "part": "construction"}, + # FIXTURE-CONSTRUCTION: SetupA.fixture_session + {"cls": "SetupA", "meth": "fixture_session", "part": "construction"}, + {"cls": "SetupFeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlySetupFeature", "meth": "do_something", "category": "feature"}, + [ + ( + # FIXTURE-CONSTRUCTION: ScenarioAChild1.fixture_session + {"cls": "ScenarioAChild1", "meth": "fixture_session", "part": "construction"}, + {"cls": "FeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "FeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlyDefinedFeature", "meth": "do_something", "category": "feature"}, + ), + ( + # FIXTURE-CONSTRUCTION: ScenarioAChild2.fixture_session + {"cls": "ScenarioAChild2", "meth": "fixture_session", "part": "construction"}, + {"cls": "FeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "FeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlyDefinedFeature", "meth": "do_something", "category": "feature"}, + ) + ], + # FIXTURE-CONSTRUCTION: balderglob_fixture_setup + {"file": "balderglob.py", "meth": "balderglob_fixture_setup", "part": "construction"}, + # FIXTURE-CONSTRUCTION: SetupA.fixture_setup + {"cls": "SetupA", "meth": "fixture_setup", "part": "construction"}, + {"cls": "SetupFeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlySetupFeature", "meth": "do_something", "category": "feature"}, + [ + ( + # FIXTURE-CONSTRUCTION: ScenarioAChild1.fixture_setup + {"cls": "ScenarioAChild1", "meth": "fixture_setup", "part": "construction"}, + {"cls": "FeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "FeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlyDefinedFeature", "meth": "do_something", "category": "feature"}, + ), + ( + # FIXTURE-CONSTRUCTION: ScenarioAChild2.fixture_setup + {"cls": "ScenarioAChild2", "meth": "fixture_setup", "part": "construction"}, + {"cls": "FeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "FeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlyDefinedFeature", "meth": "do_something", "category": "feature"}, + ) + ], + [ + ( + # FIXTURE-CONSTRUCTION: balderglob_fixture_scenario + {"file": "balderglob.py", "meth": "balderglob_fixture_scenario", "part": "construction"}, + # FIXTURE-CONSTRUCTION: SetupA.fixture_scenario + {"cls": "SetupA", "meth": "fixture_scenario", "part": "construction"}, + {"cls": "SetupFeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlySetupFeature", "meth": "do_something", "category": "feature"}, + # FIXTURE-CONSTRUCTION: ScenarioAChild1.fixture_scenario + {"cls": "ScenarioAChild1", "meth": "fixture_scenario", "part": "construction"}, + {"cls": "FeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "FeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlyDefinedFeature", "meth": "do_something", "category": "feature"}, + # FIXTURE-CONSTRUCTION: balderglob_fixture_variation + {"file": "balderglob.py", "meth": "balderglob_fixture_variation", "part": "construction"}, + # FIXTURE-CONSTRUCTION: SetupA.fixture_variation + {"cls": "SetupA", "meth": "fixture_variation", "part": "construction"}, + {"cls": "SetupFeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlySetupFeature", "meth": "do_something", "category": "feature"}, + # FIXTURE-CONSTRUCTION: ScenarioAChild1.fixture_variation + {"cls": "ScenarioAChild1", "meth": "fixture_variation", "part": "construction"}, + {"cls": "SetupFeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlySetupFeature", "meth": "do_something", "category": "feature"}, + [ + ( + # FIXTURE-CONSTRUCTION: balderglob_fixture_testcase + {"file": "balderglob.py", "meth": "balderglob_fixture_testcase", "part": "construction"}, + # FIXTURE-CONSTRUCTION: SetupA.fixture_testcase + {"cls": "SetupA", "meth": "fixture_testcase", "part": "construction"}, + {"cls": "SetupFeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlySetupFeature", "meth": "do_something", "category": "feature"}, + # FIXTURE-CONSTRUCTION: ScenarioAChild1.fixture_testcase + {"cls": "ScenarioAChild1", "meth": "fixture_testcase", "part": "construction"}, + {"cls": "SetupFeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlySetupFeature", "meth": "do_something", "category": "feature"}, + # TESTCASE: ScenarioAChild1.test_a_1 + {"cls": "ScenarioAChild1", "meth": "test_a_1"}, + {"cls": "SetupFeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlySetupFeature", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: ScenarioAChild1.fixture_testcase + {"cls": "ScenarioAChild1", "meth": "fixture_testcase", "part": "teardown"}, + {"cls": "SetupFeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlySetupFeature", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: SetupA.fixture_testcase + {"cls": "SetupA", "meth": "fixture_testcase", "part": "teardown"}, + {"cls": "SetupFeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlySetupFeature", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: balderglob_fixture_testcase + {"file": "balderglob.py", "meth": "balderglob_fixture_testcase", "part": "teardown"}, + ), + ( + # FIXTURE-CONSTRUCTION: balderglob_fixture_testcase + {"file": "balderglob.py", "meth": "balderglob_fixture_testcase", "part": "construction"}, + # FIXTURE-CONSTRUCTION: SetupA.fixture_testcase + {"cls": "SetupA", "meth": "fixture_testcase", "part": "construction"}, + {"cls": "SetupFeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlySetupFeature", "meth": "do_something", "category": "feature"}, + # FIXTURE-CONSTRUCTION: ScenarioAChild1.fixture_testcase + {"cls": "ScenarioAChild1", "meth": "fixture_testcase", "part": "construction"}, + {"cls": "SetupFeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlySetupFeature", "meth": "do_something", "category": "feature"}, + # TESTCASE: ScenarioAChild1.test_a_2 + {"cls": "ScenarioAChild1", "meth": "test_a_2"}, + {"cls": "SetupFeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlySetupFeature", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: ScenarioAChild1.fixture_testcase + {"cls": "ScenarioAChild1", "meth": "fixture_testcase", "part": "teardown"}, + {"cls": "SetupFeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlySetupFeature", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: SetupA.fixture_testcase + {"cls": "SetupA", "meth": "fixture_testcase", "part": "teardown"}, + {"cls": "SetupFeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlySetupFeature", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: balderglob_fixture_testcase + {"file": "balderglob.py", "meth": "balderglob_fixture_testcase", "part": "teardown"}, + ), + ], + # FIXTURE-TEARDOWN: ScenarioAChild1.fixture_variation + {"cls": "ScenarioAChild1", "meth": "fixture_variation", "part": "teardown"}, + {"cls": "SetupFeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlySetupFeature", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: SetupA.fixture_variation + {"cls": "SetupA", "meth": "fixture_variation", "part": "teardown"}, + {"cls": "SetupFeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlySetupFeature", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: balderglob_fixture_variation + {"file": "balderglob.py", "meth": "balderglob_fixture_variation", "part": "teardown"}, + # FIXTURE-TEARDOWN: ScenarioAChild1.fixture_scenario + {"cls": "ScenarioAChild1", "meth": "fixture_scenario", "part": "teardown"}, + {"cls": "FeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "FeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlyDefinedFeature", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: SetupA.fixture_scenario + {"cls": "SetupA", "meth": "fixture_scenario", "part": "teardown"}, + {"cls": "SetupFeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlySetupFeature", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: balderglob_fixture_scenario + {"file": "balderglob.py", "meth": "balderglob_fixture_scenario", "part": "teardown"}, + ), + ( + # FIXTURE-CONSTRUCTION: balderglob_fixture_scenario + {"file": "balderglob.py", "meth": "balderglob_fixture_scenario", "part": "construction"}, + # FIXTURE-CONSTRUCTION: SetupA.fixture_scenario + {"cls": "SetupA", "meth": "fixture_scenario", "part": "construction"}, + {"cls": "SetupFeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlySetupFeature", "meth": "do_something", "category": "feature"}, + # FIXTURE-CONSTRUCTION: ScenarioAChild2.fixture_scenario + {"cls": "ScenarioAChild2", "meth": "fixture_scenario", "part": "construction"}, + {"cls": "FeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "FeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlyDefinedFeature", "meth": "do_something", "category": "feature"}, + # FIXTURE-CONSTRUCTION: balderglob_fixture_variation + {"file": "balderglob.py", "meth": "balderglob_fixture_variation", "part": "construction"}, + # FIXTURE-CONSTRUCTION: SetupA.fixture_variation + {"cls": "SetupA", "meth": "fixture_variation", "part": "construction"}, + {"cls": "SetupFeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlySetupFeature", "meth": "do_something", "category": "feature"}, + # FIXTURE-CONSTRUCTION: ScenarioAChild2.fixture_variation + {"cls": "ScenarioAChild2", "meth": "fixture_variation", "part": "construction"}, + {"cls": "SetupFeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlySetupFeature", "meth": "do_something", "category": "feature"}, + [ + ( + # FIXTURE-CONSTRUCTION: balderglob_fixture_testcase + {"file": "balderglob.py", "meth": "balderglob_fixture_testcase", "part": "construction"}, + # FIXTURE-CONSTRUCTION: SetupA.fixture_testcase + {"cls": "SetupA", "meth": "fixture_testcase", "part": "construction"}, + {"cls": "SetupFeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlySetupFeature", "meth": "do_something", "category": "feature"}, + # FIXTURE-CONSTRUCTION: ScenarioAChild2.fixture_testcase + {"cls": "ScenarioAChild2", "meth": "fixture_testcase", "part": "construction"}, + {"cls": "SetupFeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlySetupFeature", "meth": "do_something", "category": "feature"}, + # TESTCASE: ScenarioAChild2.test_a_1 + {"cls": "ScenarioAChild2", "meth": "test_a_1"}, + {"cls": "SetupFeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlySetupFeature", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: ScenarioAChild2.fixture_testcase + {"cls": "ScenarioAChild2", "meth": "fixture_testcase", "part": "teardown"}, + {"cls": "SetupFeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlySetupFeature", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: SetupA.fixture_testcase + {"cls": "SetupA", "meth": "fixture_testcase", "part": "teardown"}, + {"cls": "SetupFeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlySetupFeature", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: balderglob_fixture_testcase + {"file": "balderglob.py", "meth": "balderglob_fixture_testcase", "part": "teardown"}, + ), + ( + # FIXTURE-CONSTRUCTION: balderglob_fixture_testcase + {"file": "balderglob.py", "meth": "balderglob_fixture_testcase", "part": "construction"}, + # FIXTURE-CONSTRUCTION: SetupA.fixture_testcase + {"cls": "SetupA", "meth": "fixture_testcase", "part": "construction"}, + {"cls": "SetupFeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlySetupFeature", "meth": "do_something", "category": "feature"}, + # FIXTURE-CONSTRUCTION: ScenarioAChild2.fixture_testcase + {"cls": "ScenarioAChild2", "meth": "fixture_testcase", "part": "construction"}, + {"cls": "SetupFeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlySetupFeature", "meth": "do_something", "category": "feature"}, + # TESTCASE: ScenarioAChild2.test_a_2 + {"cls": "ScenarioAChild2", "meth": "test_a_2"}, + {"cls": "SetupFeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlySetupFeature", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: ScenarioAChild2.fixture_testcase + {"cls": "ScenarioAChild2", "meth": "fixture_testcase", "part": "teardown"}, + {"cls": "SetupFeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlySetupFeature", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: SetupA.fixture_testcase + {"cls": "SetupA", "meth": "fixture_testcase", "part": "teardown"}, + {"cls": "SetupFeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlySetupFeature", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: balderglob_fixture_testcase + {"file": "balderglob.py", "meth": "balderglob_fixture_testcase", "part": "teardown"}, + ), + ], + # FIXTURE-TEARDOWN: ScenarioAChild2.fixture_variation + {"cls": "ScenarioAChild2", "meth": "fixture_variation", "part": "teardown"}, + {"cls": "SetupFeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlySetupFeature", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: SetupA.fixture_variation + {"cls": "SetupA", "meth": "fixture_variation", "part": "teardown"}, + {"cls": "SetupFeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlySetupFeature", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: balderglob_fixture_variation + {"file": "balderglob.py", "meth": "balderglob_fixture_variation", "part": "teardown"}, + # FIXTURE-TEARDOWN: ScenarioAChild2.fixture_scenario + {"cls": "ScenarioAChild2", "meth": "fixture_scenario", "part": "teardown"}, + {"cls": "FeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "FeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlyDefinedFeature", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: SetupA.fixture_scenario + {"cls": "SetupA", "meth": "fixture_scenario", "part": "teardown"}, + {"cls": "SetupFeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlySetupFeature", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: balderglob_fixture_scenario + {"file": "balderglob.py", "meth": "balderglob_fixture_scenario", "part": "teardown"}, + ) + ], + [ + ( + # FIXTURE-TEARDOWN: ScenarioAChild1.fixture_setup + {"cls": "ScenarioAChild1", "meth": "fixture_setup", "part": "teardown"}, + {"cls": "FeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "FeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlyDefinedFeature", "meth": "do_something", "category": "feature"}, + ), + ( + # FIXTURE-TEARDOWN: ScenarioAChild2.fixture_setup + {"cls": "ScenarioAChild2", "meth": "fixture_setup", "part": "teardown"}, + {"cls": "FeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "FeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlyDefinedFeature", "meth": "do_something", "category": "feature"}, + ) + ], + # FIXTURE-TEARDOWN: SetupA.fixture_setup + {"cls": "SetupA", "meth": "fixture_setup", "part": "teardown"}, + {"cls": "SetupFeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlySetupFeature", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: balderglob_fixture_setup + {"file": "balderglob.py", "meth": "balderglob_fixture_setup", "part": "teardown"}, + [ + ( + # FIXTURE-TEARDOWN: ScenarioAChild1.fixture_session + {"cls": "ScenarioAChild1", "meth": "fixture_session", "part": "teardown"}, + {"cls": "FeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "FeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlyDefinedFeature", "meth": "do_something", "category": "feature"}, + ), + ( + # FIXTURE-TEARDOWN: ScenarioAChild2.fixture_session + {"cls": "ScenarioAChild2", "meth": "fixture_session", "part": "teardown"}, + {"cls": "FeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "FeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlyDefinedFeature", "meth": "do_something", "category": "feature"}, + ) + ], + # FIXTURE-TEARDOWN: SetupA.fixture_session + {"cls": "SetupA", "meth": "fixture_session", "part": "teardown"}, + {"cls": "SetupFeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "NewlySetupFeature", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: balderglob_fixture_session + {"file": "balderglob.py", "meth": "balderglob_fixture_session", "part": "teardown"}, + ) + + @staticmethod + def validate_finished_session(session: BalderSession): + + # check result states everywhere (have to be SUCCESS everywhere + assert session.executor_tree.executor_result == ResultState.SUCCESS, \ + "test session does not terminates with success" + + assert session.executor_tree.construct_result.result == ResultState.SUCCESS, \ + "global executor tree construct part does not set ResultState.SUCCESS" + assert session.executor_tree.body_result.result == ResultState.SUCCESS, \ + "global executor tree body part does not set ResultState.SUCCESS" + assert session.executor_tree.teardown_result.result == ResultState.SUCCESS, \ + "global executor tree teardown part does not set ResultState.SUCCESS" + for cur_setup_executor in session.executor_tree.get_setup_executors(): + assert cur_setup_executor.executor_result == ResultState.SUCCESS, \ + "the setup executor does not have result SUCCESS" + + assert cur_setup_executor.construct_result.result == ResultState.SUCCESS + assert cur_setup_executor.body_result.result == ResultState.SUCCESS + assert cur_setup_executor.teardown_result.result == ResultState.SUCCESS + + for cur_scenario_executor in cur_setup_executor.get_scenario_executors(): + assert cur_scenario_executor.executor_result == ResultState.SUCCESS, \ + "the scenario executor does not have result SUCCESS" + + assert cur_scenario_executor.construct_result.result == ResultState.SUCCESS + assert cur_scenario_executor.body_result.result == ResultState.SUCCESS + assert cur_scenario_executor.teardown_result.result == ResultState.SUCCESS + + for cur_variation_executor in cur_scenario_executor.get_variation_executors(): + assert cur_variation_executor.executor_result == ResultState.SUCCESS, \ + "the variation executor does not have result SUCCESS" + + assert cur_variation_executor.construct_result.result == ResultState.SUCCESS + assert cur_variation_executor.body_result.result == ResultState.SUCCESS + assert cur_variation_executor.teardown_result.result == ResultState.SUCCESS + + for cur_testcase_executor in cur_variation_executor.get_testcase_executors(): + assert cur_testcase_executor.executor_result == ResultState.SUCCESS, \ + "the testcase executor does not have result SUCCESS" + + assert cur_testcase_executor.construct_result.result == ResultState.SUCCESS + assert cur_testcase_executor.body_result.result == ResultState.SUCCESS + assert cur_testcase_executor.teardown_result.result == ResultState.SUCCESS diff --git a/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/__init__.py b/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/__init__.py b/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/balderglob.py b/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/balderglob.py new file mode 100644 index 00000000..232be40a --- /dev/null +++ b/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/balderglob.py @@ -0,0 +1,150 @@ +from typing import Literal, Union, List +from datetime import datetime + +import pathlib +import balder +import argparse +import logging +from multiprocessing import Queue +from .lib.utils import FixtureReturn + +logger = logging.getLogger(__file__) + + +class MyTestException(Exception): + pass + + +class RuntimeObserver: + """This is a helper object, that will be used from this test environment to observe the execution order""" + queue: Union[Queue, None] = None + + error_throwing = {} + + @staticmethod + def add_entry(file: Union[str, pathlib.Path], cls: object, meth: callable, msg: str, + category: Literal["fixture", "testcase", "feature"] = None, + part: Literal["construction", "teardown"] = None): + """ + adds a new entry and sends it over the queue + + :param file: the full filepath where the log will be generated + + :param cls: the class object, the entry is generated in + + :param meth: the method name, the entry is generated in + + :param msg: the message that should be inserted into the entry + + :param category: optional string of the category the entry is from + + :param part: optional string of the sub part the entry is from + """ + if hasattr(meth, 'fn'): + meth = meth.fn + new_dataset = { + "timestamp": datetime.now(), "file": file, "cls": "" if cls is None else cls.__name__, + "meth": meth.__name__, "msg": msg, "category": category, "part": part + } + logger.info("{:22} | {:20} | {:30} | {:12} | {:15} | {}".format( + pathlib.Path(file).parts[-1], "" if cls is None else cls.__name__, "" if meth is None else meth.__name__, + "" if category is None else category, "" if part is None else part, "" if msg is None else msg)) + + RuntimeObserver.queue.put(new_dataset) + # check if we have to throw the error + error_throwing_required = len(RuntimeObserver.error_throwing) > 0 + for cur_key in RuntimeObserver.error_throwing.keys(): + new_dataset_val = new_dataset[cur_key] + if callable(new_dataset_val): + new_dataset_val = new_dataset_val.__name__ + if new_dataset_val != RuntimeObserver.error_throwing[cur_key]: + error_throwing_required = False + break + if error_throwing_required: + raise MyTestException(f'raise test triggered exception for `{str(RuntimeObserver.error_throwing)}`') + + +class MyErrorThrowingPlugin(balder.BalderPlugin): + """ + This is a plugin that reads the values from console arguments and sets these values into the + :class:`RuntimeObserver`. The static method `RuntimeObserver.add_entry` will automatically throw an exception on the + given position. + """ + + def addoption(self, argument_parser: argparse.ArgumentParser): + argument_parser.add_argument('--test-error-file', help='the file id, the error should be thrown in') + argument_parser.add_argument('--test-error-cls', help='the class id, the error should be thrown in') + argument_parser.add_argument('--test-error-meth', help='the meth id, the error should be thrown in') + argument_parser.add_argument('--test-error-part', help='the part (`construct` or `teardown`), the error should ' + 'be thrown in - only for fixtures') + + def modify_collected_pyfiles(self, pyfiles: List[pathlib.Path]) -> List[pathlib.Path]: + # use this method to set the values + RuntimeObserver.error_throwing = {} + if self.balder_session.parsed_args.test_error_file: + path = pathlib.Path(self.balder_session.parsed_args.test_error_file) + if not path.is_absolute(): + path = str(self.balder_session.working_dir.joinpath(path)) + RuntimeObserver.error_throwing['file'] = path + if self.balder_session.parsed_args.test_error_cls: + RuntimeObserver.error_throwing['cls'] = self.balder_session.parsed_args.test_error_cls + if self.balder_session.parsed_args.test_error_meth: + RuntimeObserver.error_throwing['meth'] = self.balder_session.parsed_args.test_error_meth + if self.balder_session.parsed_args.test_error_part: + RuntimeObserver.error_throwing['part'] = self.balder_session.parsed_args.test_error_part + return pyfiles + + +@balder.fixture(level="session") +def balderglob_fixture_session(): + RuntimeObserver.add_entry(__file__, None, balderglob_fixture_session, "begin execution CONSTRUCTION of fixture", + category="fixture", part="construction") + + yield FixtureReturn.BALDERGLOB_SESSION + + RuntimeObserver.add_entry(__file__, None, balderglob_fixture_session, "begin execution TEARDOWN of fixture", + category="fixture", part="teardown") + + +@balder.fixture(level="setup") +def balderglob_fixture_setup(): + RuntimeObserver.add_entry(__file__, None, balderglob_fixture_setup, "begin execution CONSTRUCTION of fixture", + category="fixture", part="construction") + + yield FixtureReturn.BALDERGLOB_SETUP + + RuntimeObserver.add_entry(__file__, None, balderglob_fixture_setup, "begin execution TEARDOWN of fixture", + category="fixture", part="teardown") + + +@balder.fixture(level="scenario") +def balderglob_fixture_scenario(): + RuntimeObserver.add_entry(__file__, None, balderglob_fixture_scenario, "begin execution CONSTRUCTION of fixture", + category="fixture", part="construction") + + yield FixtureReturn.BALDERGLOB_SCENARIO + + RuntimeObserver.add_entry(__file__, None, balderglob_fixture_scenario, "begin execution TEARDOWN of fixture", + category="fixture", part="teardown") + + +@balder.fixture(level="variation") +def balderglob_fixture_variation(): + RuntimeObserver.add_entry(__file__, None, balderglob_fixture_variation, "begin execution CONSTRUCTION of fixture", + category="fixture", part="construction") + + yield FixtureReturn.BALDERGLOB_VARIATION + + RuntimeObserver.add_entry(__file__, None, balderglob_fixture_variation, "begin execution TEARDOWN of fixture", + category="fixture", part="teardown") + + +@balder.fixture(level="testcase") +def balderglob_fixture_testcase(): + RuntimeObserver.add_entry(__file__, None, balderglob_fixture_testcase, "begin execution CONSTRUCTION of fixture", + category="fixture", part="construction") + + yield FixtureReturn.BALDERGLOB_TESTCASE + + RuntimeObserver.add_entry(__file__, None, balderglob_fixture_testcase, "begin execution TEARDOWN of fixture", + category="fixture", part="teardown") diff --git a/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/lib/__init__.py b/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/lib/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/lib/connections.py b/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/lib/connections.py new file mode 100644 index 00000000..cf1e8b61 --- /dev/null +++ b/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/lib/connections.py @@ -0,0 +1,11 @@ +import balder + + +@balder.insert_into_tree() +class AConnection(balder.Connection): + pass + + +@balder.insert_into_tree() +class BConnection(balder.Connection): + pass diff --git a/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/lib/features.py b/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/lib/features.py new file mode 100644 index 00000000..fae8ae25 --- /dev/null +++ b/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/lib/features.py @@ -0,0 +1,30 @@ +import balder +from ..balderglob import RuntimeObserver + + +class FeatureI(balder.Feature): + + def do_something(self): + RuntimeObserver.add_entry( + __file__, FeatureI, FeatureI.do_something, "enter `FeatureI.do_something`", category="feature") + + +class FeatureII(balder.Feature): + + def do_something(self): + RuntimeObserver.add_entry( + __file__, FeatureII, FeatureII.do_something, "enter `FeatureII.do_something`", category="feature") + + +class FeatureIII(balder.Feature): + + def do_something(self): + RuntimeObserver.add_entry( + __file__, FeatureIII, FeatureIII.do_something, "enter `FeatureIII.do_something`", category="feature") + + +class FeatureIV(balder.Feature): + + def do_something(self): + RuntimeObserver.add_entry( + __file__, FeatureIV, FeatureIV.do_something, "enter `FeatureIV.do_something`", category="feature") diff --git a/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/lib/utils.py b/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/lib/utils.py new file mode 100644 index 00000000..fe4559af --- /dev/null +++ b/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/lib/utils.py @@ -0,0 +1,22 @@ + + +class FixtureReturn: + """helper const class for return values""" + BALDERGLOB_SESSION = "balderglob_session_fixt" + BALDERGLOB_SETUP = "balderglob_setup_fixt" + BALDERGLOB_SCENARIO = "balderglob_scenario_fixt" + BALDERGLOB_VARIATION = "balderglob_variation_fixt" + BALDERGLOB_TESTCASE = "balderglob_testcase_fixt" + + SETUP_SESSION = "setup_session_fixt" + SETUP_SETUP = "setup_setup_fixt" + SETUP_SCENARIO = "setup_scenario_fixt" + SETUP_VARIATION = "setup_variation_fixt" + SETUP_TESTCASE = "setup_testcase_fixt" + + SCENARIO_SESSION = "scenario_session_fixt" + SCENARIO_SETUP = "scenario_setup_fixt" + SCENARIO_SCENARIO = "scenario_scenario_fixt" + SCENARIO_VARIATION = "scenario_variation_fixt" + SCENARIO_TESTCASE = "scenario_testcase_fixt" + diff --git a/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/scenarios/__init__.py b/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/scenarios/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/scenarios/scenario_a.py b/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/scenarios/scenario_a.py new file mode 100644 index 00000000..eedd55ab --- /dev/null +++ b/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/scenarios/scenario_a.py @@ -0,0 +1,108 @@ +import balder +import logging +from ..lib.features import FeatureI, FeatureII +from ..lib.connections import AConnection +from ..balderglob import RuntimeObserver + +logger = logging.getLogger(__file__) + + +class ScenarioA(balder.Scenario): + """This is the scenario of category A""" + + class ScenarioDevice1(balder.Device): + i = FeatureI() + + @balder.connect(ScenarioDevice1, over_connection=AConnection) + class ScenarioDevice2(balder.Device): + ii = FeatureII() + + def test_a_1(self): + RuntimeObserver.add_entry(__file__, ScenarioA, ScenarioA.test_a_1, category="testcase", + msg=f"execute Test `{ScenarioA.test_a_1.__qualname__}`") + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + + def test_a_2(self): + RuntimeObserver.add_entry(__file__, ScenarioA, ScenarioA.test_a_2, category="testcase", + msg=f"execute Test `{ScenarioA.test_a_2.__qualname__}`") + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + + @balder.fixture(level="session") + def fixture_session(self): + RuntimeObserver.add_entry(__file__, ScenarioA, ScenarioA.fixture_session, category="fixture", + part="construction", msg="begin execution CONSTRUCTION of fixture") + + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + + yield + + RuntimeObserver.add_entry(__file__, ScenarioA, ScenarioA.fixture_session, category="fixture", part="teardown", + msg="begin execution TEARDOWN of fixture") + + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + + @balder.fixture(level="setup") + def fixture_setup(self): + RuntimeObserver.add_entry(__file__, ScenarioA, ScenarioA.fixture_setup, category="fixture", part="construction", + msg="begin execution CONSTRUCTION of fixture") + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + + yield + + RuntimeObserver.add_entry(__file__, ScenarioA, ScenarioA.fixture_setup, category="fixture", part="teardown", + msg="begin execution TEARDOWN of fixture") + + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + + @balder.fixture(level="scenario") + def fixture_scenario(self): + RuntimeObserver.add_entry(__file__, ScenarioA, ScenarioA.fixture_scenario, category="fixture", + part="construction", msg="begin execution CONSTRUCTION of fixture") + + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + + yield + + RuntimeObserver.add_entry(__file__, ScenarioA, ScenarioA.fixture_scenario, category="fixture", part="teardown", + msg="begin execution TEARDOWN of fixture") + + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + + @balder.fixture(level="variation") + def fixture_variation(self): + RuntimeObserver.add_entry(__file__, ScenarioA, ScenarioA.fixture_variation, category="fixture", + part="construction", msg="begin execution CONSTRUCTION of fixture") + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + + yield + + RuntimeObserver.add_entry(__file__, ScenarioA, ScenarioA.fixture_variation, category="fixture", part="teardown", + msg="begin execution TEARDOWN of fixture") + + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + + @balder.fixture(level="testcase") + def fixture_testcase(self): + RuntimeObserver.add_entry(__file__, ScenarioA, ScenarioA.fixture_testcase, category="fixture", + part="construction", msg="begin execution CONSTRUCTION of fixture") + + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() + + yield + + RuntimeObserver.add_entry(__file__, ScenarioA, ScenarioA.fixture_testcase, category="fixture", part="teardown", + msg="begin execution TEARDOWN of fixture") + + self.ScenarioDevice1.i.do_something() + self.ScenarioDevice2.ii.do_something() diff --git a/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/setups/__init__.py b/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/setups/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/setups/setup_a_child1.py b/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/setups/setup_a_child1.py new file mode 100644 index 00000000..91807bd7 --- /dev/null +++ b/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/setups/setup_a_child1.py @@ -0,0 +1,109 @@ +import balder +import logging +from .setup_features import SetupFeatureIOverwritten, SetupFeatureII, SetupFeatureNew +from ..lib.connections import AConnection +from ..balderglob import RuntimeObserver +from .setup_a_parent import SetupAParent + +logger = logging.getLogger(__name__) + + +class SetupAChild1(SetupAParent): + """This is a setup of category A (exactly the same as scenario A)""" + + class SetupDevice1(SetupAParent.SetupDevice1): + s_i = SetupFeatureIOverwritten() + + @balder.connect(SetupDevice1, over_connection=AConnection) + class SetupDevice2(SetupAParent.SetupDevice2): + new = SetupFeatureNew() + + @balder.fixture(level="session") + def fixture_session(self): + RuntimeObserver.add_entry(__file__, SetupAChild1, SetupAChild1.fixture_session, category="fixture", + part="construction", msg="begin execution CONSTRUCTION of fixture") + + self.SetupDevice1.s_i.do_something() + self.SetupDevice2.s_ii.do_something() + self.SetupDevice2.new.do_something() + + yield + + RuntimeObserver.add_entry(__file__, SetupAChild1, SetupAChild1.fixture_session, category="fixture", + part="teardown", msg="begin execution TEARDOWN of fixture") + + self.SetupDevice1.s_i.do_something() + self.SetupDevice2.s_ii.do_something() + self.SetupDevice2.new.do_something() + + @balder.fixture(level="setup") + def fixture_setup(self): + RuntimeObserver.add_entry(__file__, SetupAChild1, SetupAChild1.fixture_setup, category="fixture", + part="construction", msg="begin execution CONSTRUCTION of fixture") + + self.SetupDevice1.s_i.do_something() + self.SetupDevice2.s_ii.do_something() + self.SetupDevice2.new.do_something() + + yield + + RuntimeObserver.add_entry(__file__, SetupAChild1, SetupAChild1.fixture_setup, category="fixture", part="teardown", + msg="begin execution TEARDOWN of fixture") + + self.SetupDevice1.s_i.do_something() + self.SetupDevice2.s_ii.do_something() + self.SetupDevice2.new.do_something() + + @balder.fixture(level="scenario") + def fixture_scenario(self): + RuntimeObserver.add_entry(__file__, SetupAChild1, SetupAChild1.fixture_scenario, category="fixture", + part="construction", msg="begin execution CONSTRUCTION of fixture") + + self.SetupDevice1.s_i.do_something() + self.SetupDevice2.s_ii.do_something() + self.SetupDevice2.new.do_something() + + yield + + RuntimeObserver.add_entry(__file__, SetupAChild1, SetupAChild1.fixture_scenario, category="fixture", + part="teardown", msg="begin execution TEARDOWN of fixture") + + self.SetupDevice1.s_i.do_something() + self.SetupDevice2.s_ii.do_something() + self.SetupDevice2.new.do_something() + + @balder.fixture(level="variation") + def fixture_variation(self): + RuntimeObserver.add_entry(__file__, SetupAChild1, SetupAChild1.fixture_variation, category="fixture", + part="construction", msg="begin execution CONSTRUCTION of fixture") + + self.SetupDevice1.s_i.do_something() + self.SetupDevice2.s_ii.do_something() + self.SetupDevice2.new.do_something() + + yield + + RuntimeObserver.add_entry(__file__, SetupAChild1, SetupAChild1.fixture_variation, category="fixture", + part="teardown", msg="begin execution TEARDOWN of fixture") + + self.SetupDevice1.s_i.do_something() + self.SetupDevice2.s_ii.do_something() + self.SetupDevice2.new.do_something() + + @balder.fixture(level="testcase") + def fixture_testcase(self): + RuntimeObserver.add_entry(__file__, SetupAChild1, SetupAChild1.fixture_testcase, category="fixture", + part="construction", msg="begin execution CONSTRUCTION of fixture") + + self.SetupDevice1.s_i.do_something() + self.SetupDevice2.s_ii.do_something() + self.SetupDevice2.new.do_something() + + yield + + RuntimeObserver.add_entry(__file__, SetupAChild1, SetupAChild1.fixture_testcase, category="fixture", + part="teardown", msg="begin execution TEARDOWN of fixture") + + self.SetupDevice1.s_i.do_something() + self.SetupDevice2.s_ii.do_something() + self.SetupDevice2.new.do_something() diff --git a/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/setups/setup_a_child2.py b/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/setups/setup_a_child2.py new file mode 100644 index 00000000..d78aac29 --- /dev/null +++ b/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/setups/setup_a_child2.py @@ -0,0 +1,109 @@ +import balder +import logging +from .setup_features import SetupFeatureIOverwritten, SetupFeatureII, SetupFeatureNew +from ..lib.connections import AConnection +from ..balderglob import RuntimeObserver +from .setup_a_parent import SetupAParent + +logger = logging.getLogger(__name__) + + +class SetupAChild2(SetupAParent): + """This is a setup of category A (exactly the same as scenario A)""" + + class SetupDevice1(SetupAParent.SetupDevice1): + s_i = SetupFeatureIOverwritten() + + @balder.connect(SetupDevice1, over_connection=AConnection) + class SetupDevice2(SetupAParent.SetupDevice2): + new = SetupFeatureNew() + + @balder.fixture(level="session") + def fixture_session(self): + RuntimeObserver.add_entry(__file__, SetupAChild2, SetupAChild2.fixture_session, category="fixture", + part="construction", msg="begin execution CONSTRUCTION of fixture") + + self.SetupDevice1.s_i.do_something() + self.SetupDevice2.s_ii.do_something() + self.SetupDevice2.new.do_something() + + yield + + RuntimeObserver.add_entry(__file__, SetupAChild2, SetupAChild2.fixture_session, category="fixture", + part="teardown", msg="begin execution TEARDOWN of fixture") + + self.SetupDevice1.s_i.do_something() + self.SetupDevice2.s_ii.do_something() + self.SetupDevice2.new.do_something() + + @balder.fixture(level="setup") + def fixture_setup(self): + RuntimeObserver.add_entry(__file__, SetupAChild2, SetupAChild2.fixture_setup, category="fixture", + part="construction", msg="begin execution CONSTRUCTION of fixture") + + self.SetupDevice1.s_i.do_something() + self.SetupDevice2.s_ii.do_something() + self.SetupDevice2.new.do_something() + + yield + + RuntimeObserver.add_entry(__file__, SetupAChild2, SetupAChild2.fixture_setup, category="fixture", part="teardown", + msg="begin execution TEARDOWN of fixture") + + self.SetupDevice1.s_i.do_something() + self.SetupDevice2.s_ii.do_something() + self.SetupDevice2.new.do_something() + + @balder.fixture(level="scenario") + def fixture_scenario(self): + RuntimeObserver.add_entry(__file__, SetupAChild2, SetupAChild2.fixture_scenario, category="fixture", + part="construction", msg="begin execution CONSTRUCTION of fixture") + + self.SetupDevice1.s_i.do_something() + self.SetupDevice2.s_ii.do_something() + self.SetupDevice2.new.do_something() + + yield + + RuntimeObserver.add_entry(__file__, SetupAChild2, SetupAChild2.fixture_scenario, category="fixture", + part="teardown", msg="begin execution TEARDOWN of fixture") + + self.SetupDevice1.s_i.do_something() + self.SetupDevice2.s_ii.do_something() + self.SetupDevice2.new.do_something() + + @balder.fixture(level="variation") + def fixture_variation(self): + RuntimeObserver.add_entry(__file__, SetupAChild2, SetupAChild2.fixture_variation, category="fixture", + part="construction", msg="begin execution CONSTRUCTION of fixture") + + self.SetupDevice1.s_i.do_something() + self.SetupDevice2.s_ii.do_something() + self.SetupDevice2.new.do_something() + + yield + + RuntimeObserver.add_entry(__file__, SetupAChild2, SetupAChild2.fixture_variation, category="fixture", + part="teardown", msg="begin execution TEARDOWN of fixture") + + self.SetupDevice1.s_i.do_something() + self.SetupDevice2.s_ii.do_something() + self.SetupDevice2.new.do_something() + + @balder.fixture(level="testcase") + def fixture_testcase(self): + RuntimeObserver.add_entry(__file__, SetupAChild2, SetupAChild2.fixture_testcase, category="fixture", + part="construction", msg="begin execution CONSTRUCTION of fixture") + + self.SetupDevice1.s_i.do_something() + self.SetupDevice2.s_ii.do_something() + self.SetupDevice2.new.do_something() + + yield + + RuntimeObserver.add_entry(__file__, SetupAChild2, SetupAChild2.fixture_testcase, category="fixture", + part="teardown", msg="begin execution TEARDOWN of fixture") + + self.SetupDevice1.s_i.do_something() + self.SetupDevice2.s_ii.do_something() + self.SetupDevice2.new.do_something() diff --git a/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/setups/setup_a_parent.py b/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/setups/setup_a_parent.py new file mode 100644 index 00000000..56a3a74b --- /dev/null +++ b/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/setups/setup_a_parent.py @@ -0,0 +1,98 @@ +import balder +import logging +from .setup_features import SetupFeatureI, SetupFeatureII +from ..lib.connections import AConnection +from ..balderglob import RuntimeObserver + +logger = logging.getLogger(__name__) + + +class SetupAParent(balder.Setup): + """This is a setup of category A (exactly the same as scenario A)""" + + class SetupDevice1(balder.Device): + s_i = SetupFeatureI() + + @balder.connect(SetupDevice1, over_connection=AConnection) + class SetupDevice2(balder.Device): + s_ii = SetupFeatureII(Dev1="SetupDevice1") + + @balder.fixture(level="session") + def fixture_session(self): + RuntimeObserver.add_entry(__file__, SetupAParent, SetupAParent.fixture_session, category="fixture", + part="construction", msg="begin execution CONSTRUCTION of fixture") + + self.SetupDevice1.s_i.do_something() + self.SetupDevice2.s_ii.do_something() + + yield + + RuntimeObserver.add_entry(__file__, SetupAParent, SetupAParent.fixture_session, category="fixture", + part="teardown", msg="begin execution TEARDOWN of fixture") + + self.SetupDevice1.s_i.do_something() + self.SetupDevice2.s_ii.do_something() + + @balder.fixture(level="setup") + def fixture_setup(self): + RuntimeObserver.add_entry(__file__, SetupAParent, SetupAParent.fixture_setup, category="fixture", + part="construction", msg="begin execution CONSTRUCTION of fixture") + + self.SetupDevice1.s_i.do_something() + self.SetupDevice2.s_ii.do_something() + + yield + + RuntimeObserver.add_entry(__file__, SetupAParent, SetupAParent.fixture_setup, category="fixture", + part="teardown", msg="begin execution TEARDOWN of fixture") + + self.SetupDevice1.s_i.do_something() + self.SetupDevice2.s_ii.do_something() + + @balder.fixture(level="scenario") + def fixture_scenario(self): + RuntimeObserver.add_entry(__file__, SetupAParent, SetupAParent.fixture_scenario, category="fixture", + part="construction", msg="begin execution CONSTRUCTION of fixture") + + self.SetupDevice1.s_i.do_something() + self.SetupDevice2.s_ii.do_something() + + yield + + RuntimeObserver.add_entry(__file__, SetupAParent, SetupAParent.fixture_scenario, category="fixture", + part="teardown", msg="begin execution TEARDOWN of fixture") + + self.SetupDevice1.s_i.do_something() + self.SetupDevice2.s_ii.do_something() + + @balder.fixture(level="variation") + def fixture_variation(self): + RuntimeObserver.add_entry(__file__, SetupAParent, SetupAParent.fixture_variation, category="fixture", + part="construction", msg="begin execution CONSTRUCTION of fixture") + + self.SetupDevice1.s_i.do_something() + self.SetupDevice2.s_ii.do_something() + + yield + + RuntimeObserver.add_entry(__file__, SetupAParent, SetupAParent.fixture_variation, category="fixture", + part="teardown", msg="begin execution TEARDOWN of fixture") + + self.SetupDevice1.s_i.do_something() + self.SetupDevice2.s_ii.do_something() + + @balder.fixture(level="testcase") + def fixture_testcase(self): + RuntimeObserver.add_entry(__file__, SetupAParent, SetupAParent.fixture_testcase, category="fixture", + part="construction", msg="begin execution CONSTRUCTION of fixture") + + self.SetupDevice1.s_i.do_something() + self.SetupDevice2.s_ii.do_something() + + yield + + RuntimeObserver.add_entry(__file__, SetupAParent, SetupAParent.fixture_testcase, category="fixture", + part="teardown", msg="begin execution TEARDOWN of fixture") + + self.SetupDevice1.s_i.do_something() + self.SetupDevice2.s_ii.do_something() diff --git a/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/setups/setup_features/__init__.py b/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/setups/setup_features/__init__.py new file mode 100644 index 00000000..5c1fa884 --- /dev/null +++ b/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/setups/setup_features/__init__.py @@ -0,0 +1,11 @@ +from .feature_i import SetupFeatureI +from .feature_ii import SetupFeatureII +from .feature_i_overwritten import SetupFeatureIOverwritten +from .feature_new import SetupFeatureNew + +__all__ = [ + "SetupFeatureI", + "SetupFeatureII", + "SetupFeatureIOverwritten", + "SetupFeatureNew" +] diff --git a/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/setups/setup_features/feature_i.py b/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/setups/setup_features/feature_i.py new file mode 100644 index 00000000..8f4cd2e5 --- /dev/null +++ b/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/setups/setup_features/feature_i.py @@ -0,0 +1,10 @@ +from ...lib.features import FeatureI +from ...balderglob import RuntimeObserver + + +class SetupFeatureI(FeatureI): + + def do_something(self): + RuntimeObserver.add_entry( + __file__, SetupFeatureI, SetupFeatureI.do_something, "enter `SetupFeatureI.do_something`", + category="feature") diff --git a/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/setups/setup_features/feature_i_overwritten.py b/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/setups/setup_features/feature_i_overwritten.py new file mode 100644 index 00000000..d884ad1e --- /dev/null +++ b/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/setups/setup_features/feature_i_overwritten.py @@ -0,0 +1,10 @@ +from ...balderglob import RuntimeObserver +from .feature_i import SetupFeatureI + + +class SetupFeatureIOverwritten(SetupFeatureI): + + def do_something(self): + RuntimeObserver.add_entry( + __file__, SetupFeatureIOverwritten, SetupFeatureIOverwritten.do_something, + "enter `SetupFeatureIOverwritten.do_something`", category="feature") diff --git a/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/setups/setup_features/feature_ii.py b/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/setups/setup_features/feature_ii.py new file mode 100644 index 00000000..b8d60a94 --- /dev/null +++ b/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/setups/setup_features/feature_ii.py @@ -0,0 +1,14 @@ +import balder +from ...lib.features import FeatureI, FeatureII +from ...balderglob import RuntimeObserver + + +class SetupFeatureII(FeatureII): + + class Dev1(balder.VDevice): + feat = FeatureI() + + def do_something(self): + RuntimeObserver.add_entry( + __file__, SetupFeatureII, SetupFeatureII.do_something, "enter `SetupFeatureII.do_something`", + category="feature") diff --git a/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/setups/setup_features/feature_new.py b/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/setups/setup_features/feature_new.py new file mode 100644 index 00000000..37af7316 --- /dev/null +++ b/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/env/setups/setup_features/feature_new.py @@ -0,0 +1,10 @@ +import balder +from ...balderglob import RuntimeObserver + + +class SetupFeatureNew(balder.Feature): + + def do_something(self): + RuntimeObserver.add_entry( + __file__, SetupFeatureNew, SetupFeatureNew.do_something, "enter `SetupFeatureNew.do_something`", + category="feature") diff --git a/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/test_0_setup_correctly_overwrite_and_add_feature_without_redefining.py b/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/test_0_setup_correctly_overwrite_and_add_feature_without_redefining.py new file mode 100644 index 00000000..7cce0f99 --- /dev/null +++ b/tests/setup_inheritance/test_0_setup_correctly_overwrite_and_add_feature_without_redefining/test_0_setup_correctly_overwrite_and_add_feature_without_redefining.py @@ -0,0 +1,364 @@ +from _balder.testresult import ResultState +from _balder.balder_session import BalderSession + +from tests.test_utilities.base_0_envtester_class import Base0EnvtesterClass + + +class Test0SetupInheritanceCorrectlyOverwriteAndAddFeatureWithoutRedefining(Base0EnvtesterClass): + """ + This testcase executes the basic envtester environment but uses an inherited setup `SetupAChild1`. Within this + setup we define an additional feature class that was not known in parent setup `SetupAParent`. In addition + to that, the environment overwrites an existing feature within the `SetupAChild1`-Device that is a child class of + the overwritten one. It will not redefine the feature `ii = SetupFeatureII()` of `SetupDevice2`. This FeatureII also + defines a VDev relation to `Device1`. It defines two child setups and it will be expected that both are executed. + + The test secures that it can be executed correctly and without an error. + """ + + @property + def expected_data(self) -> tuple: + return ( + # FIXTURE-CONSTRUCTION: balderglob_fixture_session + {"file": "balderglob.py", "meth": "balderglob_fixture_session", "part": "construction"}, + [ + ( + # FIXTURE-CONSTRUCTION: SetupAChild1.fixture_session + {"cls": "SetupAChild1", "meth": "fixture_session", "part": "construction"}, + {"cls": "SetupFeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureNew", "meth": "do_something", "category": "feature"}, + ), + ( + # FIXTURE-CONSTRUCTION: SetupAChild2.fixture_session + {"cls": "SetupAChild2", "meth": "fixture_session", "part": "construction"}, + {"cls": "SetupFeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureNew", "meth": "do_something", "category": "feature"}, + ) + ], + # FIXTURE-CONSTRUCTION: ScenarioA.fixture_session + {"cls": "ScenarioA", "meth": "fixture_session", "part": "construction"}, + {"cls": "FeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "FeatureII", "meth": "do_something", "category": "feature"}, + [ + ( + # FIXTURE-CONSTRUCTION: balderglob_fixture_setup + {"file": "balderglob.py", "meth": "balderglob_fixture_setup", "part": "construction"}, + # FIXTURE-CONSTRUCTION: SetupAChild1.fixture_setup + {"cls": "SetupAChild1", "meth": "fixture_setup", "part": "construction"}, + {"cls": "SetupFeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureNew", "meth": "do_something", "category": "feature"}, + # FIXTURE-CONSTRUCTION: ScenarioA.fixture_setup + {"cls": "ScenarioA", "meth": "fixture_setup", "part": "construction"}, + {"cls": "FeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "FeatureII", "meth": "do_something", "category": "feature"}, + # FIXTURE-CONSTRUCTION: balderglob_fixture_scenario + {"file": "balderglob.py", "meth": "balderglob_fixture_scenario", "part": "construction"}, + # FIXTURE-CONSTRUCTION: SetupAChild1.fixture_scenario + {"cls": "SetupAChild1", "meth": "fixture_scenario", "part": "construction"}, + {"cls": "SetupFeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureNew", "meth": "do_something", "category": "feature"}, + # FIXTURE-CONSTRUCTION: ScenarioA.fixture_scenario + {"cls": "ScenarioA", "meth": "fixture_scenario", "part": "construction"}, + {"cls": "FeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "FeatureII", "meth": "do_something", "category": "feature"}, + # FIXTURE-CONSTRUCTION: balderglob_fixture_variation + {"file": "balderglob.py", "meth": "balderglob_fixture_variation", "part": "construction"}, + # FIXTURE-CONSTRUCTION: SetupAChild1.fixture_variation + {"cls": "SetupAChild1", "meth": "fixture_variation", "part": "construction"}, + {"cls": "SetupFeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureNew", "meth": "do_something", "category": "feature"}, + # FIXTURE-CONSTRUCTION: ScenarioA.fixture_variation + {"cls": "ScenarioA", "meth": "fixture_variation", "part": "construction"}, + {"cls": "SetupFeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + [ + ( + # FIXTURE-CONSTRUCTION: balderglob_fixture_testcase + {"file": "balderglob.py", "meth": "balderglob_fixture_testcase", "part": "construction"}, + # FIXTURE-CONSTRUCTION: SetupAChild1.fixture_testcase + {"cls": "SetupAChild1", "meth": "fixture_testcase", "part": "construction"}, + {"cls": "SetupFeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureNew", "meth": "do_something", "category": "feature"}, + # FIXTURE-CONSTRUCTION: ScenarioA.fixture_testcase + {"cls": "ScenarioA", "meth": "fixture_testcase", "part": "construction"}, + {"cls": "SetupFeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + # TESTCASE: ScenarioA.test_a_1 + {"cls": "ScenarioA", "meth": "test_a_1"}, + {"cls": "SetupFeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: ScenarioA.fixture_testcase + {"cls": "ScenarioA", "meth": "fixture_testcase", "part": "teardown"}, + {"cls": "SetupFeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: SetupAChild1.fixture_testcase + {"cls": "SetupAChild1", "meth": "fixture_testcase", "part": "teardown"}, + {"cls": "SetupFeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureNew", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: balderglob_fixture_testcase + {"file": "balderglob.py", "meth": "balderglob_fixture_testcase", "part": "teardown"}, + ), + ( + # FIXTURE-CONSTRUCTION: balderglob_fixture_testcase + {"file": "balderglob.py", "meth": "balderglob_fixture_testcase", "part": "construction"}, + # FIXTURE-CONSTRUCTION: SetupAChild1.fixture_testcase + {"cls": "SetupAChild1", "meth": "fixture_testcase", "part": "construction"}, + {"cls": "SetupFeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureNew", "meth": "do_something", "category": "feature"}, + # FIXTURE-CONSTRUCTION: ScenarioA.fixture_testcase + {"cls": "ScenarioA", "meth": "fixture_testcase", "part": "construction"}, + {"cls": "SetupFeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + # TESTCASE: ScenarioA.test_a_2 + {"cls": "ScenarioA", "meth": "test_a_2"}, + {"cls": "SetupFeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: ScenarioA.fixture_testcase + {"cls": "ScenarioA", "meth": "fixture_testcase", "part": "teardown"}, + {"cls": "SetupFeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: SetupAChild1.fixture_testcase + {"cls": "SetupAChild1", "meth": "fixture_testcase", "part": "teardown"}, + {"cls": "SetupFeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureNew", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: balderglob_fixture_testcase + {"file": "balderglob.py", "meth": "balderglob_fixture_testcase", "part": "teardown"}, + ), + ], + # FIXTURE-TEARDOWN: ScenarioA.fixture_variation + {"cls": "ScenarioA", "meth": "fixture_variation", "part": "teardown"}, + {"cls": "SetupFeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: SetupAChild1.fixture_variation + {"cls": "SetupAChild1", "meth": "fixture_variation", "part": "teardown"}, + {"cls": "SetupFeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureNew", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: balderglob_fixture_variation + {"file": "balderglob.py", "meth": "balderglob_fixture_variation", "part": "teardown"}, + # FIXTURE-TEARDOWN: ScenarioA.fixture_scenario + {"cls": "ScenarioA", "meth": "fixture_scenario", "part": "teardown"}, + {"cls": "FeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "FeatureII", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: SetupAChild1.fixture_scenario + {"cls": "SetupAChild1", "meth": "fixture_scenario", "part": "teardown"}, + {"cls": "SetupFeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureNew", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: balderglob_fixture_scenario + {"file": "balderglob.py", "meth": "balderglob_fixture_scenario", "part": "teardown"}, + # FIXTURE-TEARDOWN: ScenarioA.fixture_setup + {"cls": "ScenarioA", "meth": "fixture_setup", "part": "teardown"}, + {"cls": "FeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "FeatureII", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: SetupAChild1.fixture_setup + {"cls": "SetupAChild1", "meth": "fixture_setup", "part": "teardown"}, + {"cls": "SetupFeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureNew", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: balderglob_fixture_setup + {"file": "balderglob.py", "meth": "balderglob_fixture_setup", "part": "teardown"}, + ), + ( + # FIXTURE-CONSTRUCTION: balderglob_fixture_setup + {"file": "balderglob.py", "meth": "balderglob_fixture_setup", "part": "construction"}, + # FIXTURE-CONSTRUCTION: SetupAChild2.fixture_setup + {"cls": "SetupAChild2", "meth": "fixture_setup", "part": "construction"}, + {"cls": "SetupFeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureNew", "meth": "do_something", "category": "feature"}, + # FIXTURE-CONSTRUCTION: ScenarioA.fixture_setup + {"cls": "ScenarioA", "meth": "fixture_setup", "part": "construction"}, + {"cls": "FeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "FeatureII", "meth": "do_something", "category": "feature"}, + # FIXTURE-CONSTRUCTION: balderglob_fixture_scenario + {"file": "balderglob.py", "meth": "balderglob_fixture_scenario", "part": "construction"}, + # FIXTURE-CONSTRUCTION: SetupAChild2.fixture_scenario + {"cls": "SetupAChild2", "meth": "fixture_scenario", "part": "construction"}, + {"cls": "SetupFeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureNew", "meth": "do_something", "category": "feature"}, + # FIXTURE-CONSTRUCTION: ScenarioA.fixture_scenario + {"cls": "ScenarioA", "meth": "fixture_scenario", "part": "construction"}, + {"cls": "FeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "FeatureII", "meth": "do_something", "category": "feature"}, + # FIXTURE-CONSTRUCTION: balderglob_fixture_variation + {"file": "balderglob.py", "meth": "balderglob_fixture_variation", "part": "construction"}, + # FIXTURE-CONSTRUCTION: SetupAChild2.fixture_variation + {"cls": "SetupAChild2", "meth": "fixture_variation", "part": "construction"}, + {"cls": "SetupFeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureNew", "meth": "do_something", "category": "feature"}, + # FIXTURE-CONSTRUCTION: ScenarioA.fixture_variation + {"cls": "ScenarioA", "meth": "fixture_variation", "part": "construction"}, + {"cls": "SetupFeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + [ + ( + # FIXTURE-CONSTRUCTION: balderglob_fixture_testcase + {"file": "balderglob.py", "meth": "balderglob_fixture_testcase", "part": "construction"}, + # FIXTURE-CONSTRUCTION: SetupAChild2.fixture_testcase + {"cls": "SetupAChild2", "meth": "fixture_testcase", "part": "construction"}, + {"cls": "SetupFeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureNew", "meth": "do_something", "category": "feature"}, + # FIXTURE-CONSTRUCTION: ScenarioA.fixture_testcase + {"cls": "ScenarioA", "meth": "fixture_testcase", "part": "construction"}, + {"cls": "SetupFeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + # TESTCASE: ScenarioA.test_a_1 + {"cls": "ScenarioA", "meth": "test_a_1"}, + {"cls": "SetupFeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: ScenarioA.fixture_testcase + {"cls": "ScenarioA", "meth": "fixture_testcase", "part": "teardown"}, + {"cls": "SetupFeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: SetupAChild2.fixture_testcase + {"cls": "SetupAChild2", "meth": "fixture_testcase", "part": "teardown"}, + {"cls": "SetupFeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureNew", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: balderglob_fixture_testcase + {"file": "balderglob.py", "meth": "balderglob_fixture_testcase", "part": "teardown"}, + ), + ( + # FIXTURE-CONSTRUCTION: balderglob_fixture_testcase + {"file": "balderglob.py", "meth": "balderglob_fixture_testcase", "part": "construction"}, + # FIXTURE-CONSTRUCTION: SetupAChild2.fixture_testcase + {"cls": "SetupAChild2", "meth": "fixture_testcase", "part": "construction"}, + {"cls": "SetupFeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureNew", "meth": "do_something", "category": "feature"}, + # FIXTURE-CONSTRUCTION: ScenarioA.fixture_testcase + {"cls": "ScenarioA", "meth": "fixture_testcase", "part": "construction"}, + {"cls": "SetupFeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + # TESTCASE: ScenarioA.test_a_2 + {"cls": "ScenarioA", "meth": "test_a_2"}, + {"cls": "SetupFeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: ScenarioA.fixture_testcase + {"cls": "ScenarioA", "meth": "fixture_testcase", "part": "teardown"}, + {"cls": "SetupFeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: SetupAChild2.fixture_testcase + {"cls": "SetupAChild2", "meth": "fixture_testcase", "part": "teardown"}, + {"cls": "SetupFeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureNew", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: balderglob_fixture_testcase + {"file": "balderglob.py", "meth": "balderglob_fixture_testcase", "part": "teardown"}, + ), + ], + # FIXTURE-TEARDOWN: ScenarioA.fixture_variation + {"cls": "ScenarioA", "meth": "fixture_variation", "part": "teardown"}, + {"cls": "SetupFeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: SetupAChild2.fixture_variation + {"cls": "SetupAChild2", "meth": "fixture_variation", "part": "teardown"}, + {"cls": "SetupFeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureNew", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: balderglob_fixture_variation + {"file": "balderglob.py", "meth": "balderglob_fixture_variation", "part": "teardown"}, + # FIXTURE-TEARDOWN: ScenarioA.fixture_scenario + {"cls": "ScenarioA", "meth": "fixture_scenario", "part": "teardown"}, + {"cls": "FeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "FeatureII", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: SetupAChild2.fixture_scenario + {"cls": "SetupAChild2", "meth": "fixture_scenario", "part": "teardown"}, + {"cls": "SetupFeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureNew", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: balderglob_fixture_scenario + {"file": "balderglob.py", "meth": "balderglob_fixture_scenario", "part": "teardown"}, + # FIXTURE-TEARDOWN: ScenarioA.fixture_setup + {"cls": "ScenarioA", "meth": "fixture_setup", "part": "teardown"}, + {"cls": "FeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "FeatureII", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: SetupAChild2.fixture_setup + {"cls": "SetupAChild2", "meth": "fixture_setup", "part": "teardown"}, + {"cls": "SetupFeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureNew", "meth": "do_something", "category": "feature"}, + # FIXTURE-TEARDOWN: balderglob_fixture_setup + {"file": "balderglob.py", "meth": "balderglob_fixture_setup", "part": "teardown"}, + ) + ], + # FIXTURE-TEARDOWN: ScenarioA.fixture_session + {"cls": "ScenarioA", "meth": "fixture_session", "part": "teardown"}, + {"cls": "FeatureI", "meth": "do_something", "category": "feature"}, + {"cls": "FeatureII", "meth": "do_something", "category": "feature"}, + [ + ( + # FIXTURE-TEARDOWN: SetupAChild1.fixture_session + {"cls": "SetupAChild1", "meth": "fixture_session", "part": "teardown"}, + {"cls": "SetupFeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureNew", "meth": "do_something", "category": "feature"}, + ), + ( + # FIXTURE-TEARDOWN: SetupAChild2.fixture_session + {"cls": "SetupAChild2", "meth": "fixture_session", "part": "teardown"}, + {"cls": "SetupFeatureIOverwritten", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureII", "meth": "do_something", "category": "feature"}, + {"cls": "SetupFeatureNew", "meth": "do_something", "category": "feature"}, + ) + ], + # FIXTURE-TEARDOWN: balderglob_fixture_session + {"file": "balderglob.py", "meth": "balderglob_fixture_session", "part": "teardown"}, + ) + + @staticmethod + def validate_finished_session(session: BalderSession): + + # check result states everywhere (have to be SUCCESS everywhere) + assert session.executor_tree.executor_result == ResultState.SUCCESS, \ + "test session does not terminates with success" + + assert session.executor_tree.construct_result.result == ResultState.SUCCESS, \ + "global executor tree construct part does not set ResultState.SUCCESS" + assert session.executor_tree.body_result.result == ResultState.SUCCESS, \ + "global executor tree body part does not set ResultState.SUCCESS" + assert session.executor_tree.teardown_result.result == ResultState.SUCCESS, \ + "global executor tree teardown part does not set ResultState.SUCCESS" + for cur_setup_executor in session.executor_tree.get_setup_executors(): + assert cur_setup_executor.executor_result == ResultState.SUCCESS, \ + "the setup executor does not have result SUCCESS" + + assert cur_setup_executor.construct_result.result == ResultState.SUCCESS + assert cur_setup_executor.body_result.result == ResultState.SUCCESS + assert cur_setup_executor.teardown_result.result == ResultState.SUCCESS + + for cur_scenario_executor in cur_setup_executor.get_scenario_executors(): + assert cur_scenario_executor.executor_result == ResultState.SUCCESS, \ + "the scenario executor does not have result SUCCESS" + + assert cur_scenario_executor.construct_result.result == ResultState.SUCCESS + assert cur_scenario_executor.body_result.result == ResultState.SUCCESS + assert cur_scenario_executor.teardown_result.result == ResultState.SUCCESS + + for cur_variation_executor in cur_scenario_executor.get_variation_executors(): + assert cur_variation_executor.executor_result == ResultState.SUCCESS, \ + "the variation executor does not have result SUCCESS" + + assert cur_variation_executor.construct_result.result == ResultState.SUCCESS + assert cur_variation_executor.body_result.result == ResultState.SUCCESS + assert cur_variation_executor.teardown_result.result == ResultState.SUCCESS + + for cur_testcase_executor in cur_variation_executor.get_testcase_executors(): + assert cur_testcase_executor.executor_result == ResultState.SUCCESS, \ + "the testcase executor does not have result SUCCESS" + + assert cur_testcase_executor.construct_result.result == ResultState.SUCCESS + assert cur_testcase_executor.body_result.result == ResultState.SUCCESS + assert cur_testcase_executor.teardown_result.result == ResultState.SUCCESS