Skip to content
Merged
5 changes: 3 additions & 2 deletions src/_balder/executor/basic_executable_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,9 @@ def filter_tree_for_user_filters(self):
"""
This method calls all user defined filters that are to be applied to the executor tree.
"""
for cur_child_executor in self.all_child_executors:
cur_child_executor.filter_tree_for_user_filters()
if self.all_child_executors:
for cur_child_executor in self.all_child_executors:
cur_child_executor.filter_tree_for_user_filters()

def execute(self, show_discarded=False):
"""
Expand Down
9 changes: 5 additions & 4 deletions src/_balder/executor/basic_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def __init__(self):

@property
@abstractmethod
def all_child_executors(self) -> List[BasicExecutor]:
def all_child_executors(self) -> list[BasicExecutor] | None:
"""
returns all child executors of this object or None if no child executors can exist (this element is a leaf)
"""
Expand Down Expand Up @@ -185,8 +185,9 @@ def filter_tree_for_user_filters(self):
"""
This method calls all user defined filters that are to be applied to the executor tree.
"""
for cur_child_executor in self.all_child_executors:
cur_child_executor.filter_tree_for_user_filters()
if self.all_child_executors:
for cur_child_executor in self.all_child_executors:
cur_child_executor.filter_tree_for_user_filters()

def testsummary(self) -> ResultSummary:
"""
Expand All @@ -198,7 +199,7 @@ def testsummary(self) -> ResultSummary:

if isinstance(self.body_result, TestcaseResult):
setattr(summary, self.executor_result.value, 1)
else:
elif self.all_child_executors:
for cur_child_exec in self.all_child_executors:
summary += cur_child_exec.testsummary()
return summary
2 changes: 1 addition & 1 deletion src/_balder/executor/executor_tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def __init__(self, fixture_manager: FixtureManager):
# ---------------------------------- PROPERTIES --------------------------------------------------------------------

@property
def all_child_executors(self) -> List[BasicExecutableExecutor]:
def all_child_executors(self) -> List[BasicExecutableExecutor] | None:
return self._setup_executors

@property
Expand Down
57 changes: 17 additions & 40 deletions src/_balder/executor/unresolved_parametrized_testcase_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,6 @@ def __init__(
# holds the specific static parameters for this unresolved group
self._static_parameters = static_parameters if static_parameters is not None else {}

# holds the dynamically created testcase executors as soon as this executor is entered
self._testcase_executors = None

# contains the result object for the BODY part of this branch
self.body_result = BranchBodyResult(self)

Expand All @@ -53,8 +50,8 @@ def base_testcase_callable(self) -> callable:
return self._base_testcase_callable

@property
def all_child_executors(self) -> List[ParametrizedTestcaseExecutor]:
return self.get_testcase_executors()
def all_child_executors(self) -> None:
return None

@property
def base_testcase_obj(self) -> Scenario:
Expand All @@ -69,24 +66,6 @@ def base_instance(self) -> object:
returns the base class instance to which this executor instance belongs"""
return self._base_testcase_callable

@property
def parametrization_has_been_resolved(self) -> bool:
"""returns true if the parametrization has been resolved"""
return self._testcase_executors is not None

def has_runnable_tests(self, consider_discarded_too=False) -> bool:
if self.parametrization_has_been_resolved:
return super().has_runnable_tests(consider_discarded_too=consider_discarded_too)

allowed_prev_marks = [PreviousExecutorMark.RUNNABLE]

if consider_discarded_too:
allowed_prev_marks.append(PreviousExecutorMark.DISCARDED)

if self.prev_mark not in allowed_prev_marks:
return False
return True

def has_skipped_tests(self) -> bool:
return self.prev_mark == PreviousExecutorMark.SKIP

Expand Down Expand Up @@ -117,29 +96,27 @@ def get_covered_by_element(self) -> List[Scenario | callable]:
all_covered_by_data.extend(covered_by_dict.get(None, []))
return all_covered_by_data

def get_testcase_executors(self) -> List[ParametrizedTestcaseExecutor | UnresolvedParametrizedTestcaseExecutor]:
"""returns all sub testcase executors that belongs to this variation-executor"""
if self._testcase_executors is None:
return [self]
return self._testcase_executors

def resolve_dynamic_parametrization(self):
def get_resolved_parametrized_testcase_executors(self):
"""
resolves the dynamic parametrization - should be called when setup features are active in the scenario
"""
self._testcase_executors = []
executors = []

parametrization = self.get_parametrization()
if parametrization:
for cur_parametrization in parametrization:
self._testcase_executors.append(
ParametrizedTestcaseExecutor(
self._base_testcase_callable,
parent=self.parent_executor,
parametrization=cur_parametrization,
unresolved_group_obj=self
)

if not parametrization:
return []

for cur_parametrization in parametrization:
executors.append(
ParametrizedTestcaseExecutor(
self._base_testcase_callable,
parent=self.parent_executor,
parametrization=cur_parametrization,
unresolved_group_obj=self
)
)
return executors

def get_parametrization(self) -> List[OrderedDict[str, Any]] | None:
"""
Expand Down
21 changes: 9 additions & 12 deletions src/_balder/executor/variation_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ def _prepare_execution(self, show_discarded):
self.exchange_unmapped_vdevice_references()
self.update_vdevice_referenced_feature_instances()
self.set_conn_dependent_methods()
self.resolve_possible_parametrization()
self.resolve_and_exchange_unresolved_parametrization()

def _body_execution(self, show_discarded):
if show_discarded and not self.can_be_applied():
Expand Down Expand Up @@ -332,16 +332,9 @@ def testsummary(self) -> ResultSummary:
return super().testsummary()
return ResultSummary()

def get_testcase_executors(self) -> List[TestcaseExecutor]:
def get_testcase_executors(self) -> List[TestcaseExecutor | UnresolvedParametrizedTestcaseExecutor]:
"""returns all sub testcase executors that belongs to this variation-executor"""
result = []
for cur_executor in self._testcase_executors:
if (isinstance(cur_executor, UnresolvedParametrizedTestcaseExecutor) and
cur_executor.parametrization_has_been_resolved):
result += cur_executor.get_testcase_executors()
else:
result.append(cur_executor)
return result
return self._testcase_executors.copy()

def add_testcase_executor(self, testcase_executor: TestcaseExecutor | UnresolvedParametrizedTestcaseExecutor):
"""
Expand Down Expand Up @@ -878,8 +871,12 @@ def set_conn_dependent_methods(self):

cur_setup_feature_controller.set_active_method_variation(method_selection=method_var_selection)

def resolve_possible_parametrization(self):
def resolve_and_exchange_unresolved_parametrization(self):
"""resolves the parametrization if there are any :class:`UnresolvedParametrizedTestcaseExecutor` in the tree"""
replaced_executors = []
for cur_child in self._testcase_executors:
if isinstance(cur_child, UnresolvedParametrizedTestcaseExecutor):
cur_child.resolve_dynamic_parametrization()
replaced_executors.extend(cur_child.get_resolved_parametrized_testcase_executors())
else:
replaced_executors.append(cur_child)
self._testcase_executors = replaced_executors
7 changes: 4 additions & 3 deletions src/_balder/testresult.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,10 @@ def result(self):
"""returns the determined result for the inner branch of the related executor"""
relative_result = ResultState.NOT_RUN
priority_order = ResultState.priority_order()
for cur_child in self._related_executor.all_child_executors:
if priority_order.index(cur_child.executor_result) < priority_order.index(relative_result):
relative_result = cur_child.executor_result
if self._related_executor.all_child_executors:
for cur_child in self._related_executor.all_child_executors:
if priority_order.index(cur_child.executor_result) < priority_order.index(relative_result):
relative_result = cur_child.executor_result
self._result = relative_result
return self._result

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ def processed(env_dir):

all_variation_executor = all_scenario_executor[0].get_variation_executors()

assert len(all_variation_executor) == 1, f"detect more than one variation executor"

assert all_variation_executor[0].executor_result == ResultState.NOT_RUN, \
"the variation executor does not have result SUCCESS"

Expand All @@ -60,7 +62,13 @@ def processed(env_dir):
assert all_variation_executor[0].teardown_result.result == ResultState.NOT_RUN

all_testcase_executor = all_variation_executor[0].get_testcase_executors()
assert len(all_testcase_executor) == 0, f"detect some testcase executor"
assert len(all_testcase_executor) == 1, f"detect some testcase executor"
assert isinstance(all_testcase_executor[0], UnresolvedParametrizedTestcaseExecutor), \
f"test case executor is from unexpected type {type(all_testcase_executor[0])}"

assert all_testcase_executor[0].construct_result.result == ResultState.NOT_RUN
assert all_testcase_executor[0].body_result.result == ResultState.NOT_RUN
assert all_testcase_executor[0].teardown_result.result == ResultState.NOT_RUN

exceptions = all_scenario_executor[0].get_all_recognized_exception()
assert len(exceptions) == 1, f"detect more than one exception executor"
Expand Down