Skip to content

Commit 3b7ff48

Browse files
committed
feat(fixture_manager.py): allow inheritance of fixtures within setup and scenario classes
1 parent f7055dd commit 3b7ff48

File tree

1 file changed

+38
-7
lines changed

1 file changed

+38
-7
lines changed

src/_balder/fixture_manager.py

+38-7
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,41 @@ def leave(self, branch: Union[BasicExecutor, ExecutorTree, SetupExecutor, Scenar
394394
if exception:
395395
raise exception
396396

397+
def get_fixture_for_class(
398+
self,
399+
execution_level: Union[Type[ExecutorTree], Type[SetupExecutor], Type[ScenarioExecutor],
400+
Type[VariationExecutor], Type[TestcaseExecutor]],
401+
setup_or_scenario_class: Union[None, Type[Setup], Type[Scenario]],
402+
parent_classes: bool = True
403+
) -> List[Tuple[MethodLiteralType, Callable]]:
404+
"""
405+
This method returns all classes of a specific Setup/Scenario class for a specific execution-level.
406+
407+
:param execution_level: the execution level the fixture should be returned for
408+
:param setup_or_scenario_class: the scenario or setup class, the fixtures should be returned for
409+
:param parent_classes: true if the method should look for fixtures in parent classes too
410+
:return: list with all fixtures that are matching search criteria
411+
"""
412+
# current relevant EXECUTION LEVEL - all other levels are not relevant for this call
413+
cur_execution_level = self.resolve_type_level[execution_level]
414+
# get all fixtures of the current relevant level
415+
fixtures_of_exec_level = self.fixtures.get(cur_execution_level, {})
416+
if setup_or_scenario_class is not None and parent_classes:
417+
all_fixtures = []
418+
for cur_parent_class in inspect.getmro(setup_or_scenario_class):
419+
if issubclass(cur_parent_class, (Scenario, Setup)):
420+
all_fixtures += self.get_fixture_for_class(execution_level, cur_parent_class, False)
421+
# go through list and remove all overwritten fixtures
422+
_added_fixtures = []
423+
remaining_fixtures = []
424+
for cur_fixture_tuple in all_fixtures:
425+
if cur_fixture_tuple[1].__name__ not in _added_fixtures:
426+
_added_fixtures.append(cur_fixture_tuple[1].__name__)
427+
remaining_fixtures.append(cur_fixture_tuple)
428+
return remaining_fixtures
429+
else:
430+
return fixtures_of_exec_level.get(setup_or_scenario_class, [])
431+
397432
def get_all_fixtures_for_current_level(
398433
self, branch: Union[ExecutorTree, SetupExecutor, ScenarioExecutor, VariationExecutor, TestcaseExecutor]) \
399434
-> Dict[Union[Type[ExecutorTree], Type[Scenario], Type[Setup]],
@@ -416,28 +451,24 @@ def get_all_fixtures_for_current_level(
416451
argument (this list is ordered after the call hierarchy)
417452
"""
418453
from _balder.executor.executor_tree import ExecutorTree
419-
# current relevant EXECUTION LEVEL - all other levels are not relevant for this call
420-
cur_execution_level = self.resolve_type_level[branch.__class__]
421-
# get all fixtures of the current relevant level
422-
fixtures_of_exec_level = self.fixtures.get(cur_execution_level, {})
423454

424455
all_fixtures = {}
425456
# get all relevant fixtures of `balderglob.py` (None is key for balderglob fixtures)
426-
glob_fixtures = fixtures_of_exec_level.get(None, [])
457+
glob_fixtures = self.get_fixture_for_class(branch.__class__, None)
427458
all_fixtures[ExecutorTree] = {}
428459
all_fixtures[ExecutorTree][ExecutorTree] = glob_fixtures
429460
# get all relevant fixtures with definition scope "setup"
430461
all_fixtures[Setup] = {}
431462
for cur_setup in branch.get_all_base_instances_of_this_branch(Setup, only_runnable_elements=True):
432463
# check if there exists fixtures for the current setup
433-
cur_setup_fixtures = fixtures_of_exec_level.get(cur_setup.__class__, [])
464+
cur_setup_fixtures = self.get_fixture_for_class(branch.__class__, cur_setup.__class__)
434465
if cur_setup_fixtures:
435466
all_fixtures[Setup][cur_setup.__class__] = cur_setup_fixtures
436467

437468
# get all relevant fixtures with definition scope "scenario"
438469
all_fixtures[Scenario] = {}
439470
for cur_scenario in branch.get_all_base_instances_of_this_branch(Scenario, only_runnable_elements=True):
440-
cur_scenario_fixtures = fixtures_of_exec_level.get(cur_scenario.__class__, [])
471+
cur_scenario_fixtures = self.get_fixture_for_class(branch.__class__, cur_scenario.__class__)
441472
if cur_scenario_fixtures:
442473
all_fixtures[Scenario][cur_scenario.__class__] = cur_scenario_fixtures
443474

0 commit comments

Comments
 (0)