baldertest 0.1.0b6__py3-none-any.whl → 0.1.0b8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- _balder/_version.py +13 -1
- _balder/balder_session.py +20 -17
- _balder/collector.py +38 -6
- _balder/connection.py +137 -97
- _balder/console/balder.py +1 -0
- _balder/controllers/base_device_controller.py +2 -3
- _balder/controllers/feature_controller.py +11 -12
- _balder/exceptions.py +1 -1
- _balder/executor/basic_executor.py +35 -20
- _balder/executor/executor_tree.py +49 -36
- _balder/executor/scenario_executor.py +21 -15
- _balder/executor/setup_executor.py +15 -16
- _balder/executor/testcase_executor.py +4 -8
- _balder/executor/variation_executor.py +179 -132
- _balder/fixture_manager.py +38 -7
- _balder/previous_executor_mark.py +3 -0
- _balder/routing_path.py +1 -3
- _balder/solver.py +17 -15
- balder/exceptions.py +2 -2
- baldertest-0.1.0b8.dist-info/METADATA +388 -0
- {baldertest-0.1.0b6.dist-info → baldertest-0.1.0b8.dist-info}/RECORD +25 -25
- {baldertest-0.1.0b6.dist-info → baldertest-0.1.0b8.dist-info}/WHEEL +1 -1
- baldertest-0.1.0b6.dist-info/METADATA +0 -92
- {baldertest-0.1.0b6.dist-info → baldertest-0.1.0b8.dist-info}/LICENSE +0 -0
- {baldertest-0.1.0b6.dist-info → baldertest-0.1.0b8.dist-info}/entry_points.txt +0 -0
- {baldertest-0.1.0b6.dist-info → baldertest-0.1.0b8.dist-info}/top_level.txt +0 -0
|
@@ -87,21 +87,21 @@ class BasicExecutor(ABC):
|
|
|
87
87
|
# ---------------------------------- PROTECTED METHODS -------------------------------------------------------------
|
|
88
88
|
|
|
89
89
|
@abstractmethod
|
|
90
|
-
def _prepare_execution(self):
|
|
90
|
+
def _prepare_execution(self, show_discarded):
|
|
91
91
|
"""
|
|
92
92
|
This method runs before the branch will be executed and before the fixture construction code of this branch
|
|
93
93
|
runs.
|
|
94
94
|
"""
|
|
95
95
|
|
|
96
96
|
@abstractmethod
|
|
97
|
-
def _body_execution(self):
|
|
97
|
+
def _body_execution(self, show_discarded):
|
|
98
98
|
"""
|
|
99
99
|
This method runs between the fixture construction and teardown code. It should trigger the execution of the
|
|
100
100
|
child branches.
|
|
101
101
|
"""
|
|
102
102
|
|
|
103
103
|
@abstractmethod
|
|
104
|
-
def _cleanup_execution(self):
|
|
104
|
+
def _cleanup_execution(self, show_discarded):
|
|
105
105
|
"""
|
|
106
106
|
This method runs after the branch was executed (also after the fixture teardown code ran)
|
|
107
107
|
"""
|
|
@@ -137,17 +137,28 @@ class BasicExecutor(ABC):
|
|
|
137
137
|
if isinstance(cur_child_executor.body_result, TestcaseResult):
|
|
138
138
|
cur_child_executor.body_result.set_result(result=value, exception=None)
|
|
139
139
|
|
|
140
|
-
def
|
|
140
|
+
def has_runnable_tests(self, consider_discarded_too=False) -> bool:
|
|
141
141
|
"""
|
|
142
142
|
This method returns true if this executor element is runnable. The method returns true if this element has
|
|
143
143
|
`prev_mark=RUNNABLE` and minimum one of its children has `prev_mark=RUNNABLE` too.
|
|
144
|
+
|
|
145
|
+
:param consider_discarded_too: True if the method allows DISCARDED elements too
|
|
144
146
|
"""
|
|
145
|
-
|
|
147
|
+
allowed_prev_marks = [PreviousExecutorMark.RUNNABLE]
|
|
148
|
+
|
|
149
|
+
if consider_discarded_too:
|
|
150
|
+
allowed_prev_marks.append(PreviousExecutorMark.DISCARDED)
|
|
151
|
+
|
|
152
|
+
if self.prev_mark not in allowed_prev_marks:
|
|
146
153
|
return False
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
154
|
+
|
|
155
|
+
if self.all_child_executors is not None:
|
|
156
|
+
# the executor has child executors -> check them
|
|
157
|
+
for cur_child in self.all_child_executors:
|
|
158
|
+
if cur_child.has_runnable_tests(consider_discarded_too):
|
|
159
|
+
return True
|
|
160
|
+
return False
|
|
161
|
+
return True
|
|
151
162
|
|
|
152
163
|
def get_all_base_instances_of_this_branch(
|
|
153
164
|
self, with_type: Union[Type[Setup], Type[Scenario], Type[types.FunctionType]],
|
|
@@ -165,7 +176,7 @@ class BasicExecutor(ABC):
|
|
|
165
176
|
# only go through cur_executor == ExecutorTree (do not iterate with this object)
|
|
166
177
|
while cur_executor.parent_executor is not None:
|
|
167
178
|
if isinstance(cur_executor.base_instance, with_type):
|
|
168
|
-
if not only_runnable_elements or cur_executor.
|
|
179
|
+
if not only_runnable_elements or cur_executor.has_runnable_tests():
|
|
169
180
|
return [cur_executor.base_instance]
|
|
170
181
|
cur_executor = cur_executor.parent_executor
|
|
171
182
|
|
|
@@ -181,10 +192,12 @@ class BasicExecutor(ABC):
|
|
|
181
192
|
return list(set(result))
|
|
182
193
|
|
|
183
194
|
@abstractmethod
|
|
184
|
-
def cleanup_empty_executor_branches(self):
|
|
195
|
+
def cleanup_empty_executor_branches(self, consider_discarded=False):
|
|
185
196
|
"""
|
|
186
197
|
This method searches the whole tree and removes branches where an executor item has no own children. It can
|
|
187
198
|
remove these branches, because they have no valid matchings.
|
|
199
|
+
|
|
200
|
+
:param consider_discarded: true if this method should consider discarded branches, otherwise False
|
|
188
201
|
"""
|
|
189
202
|
|
|
190
203
|
def filter_tree_for_user_filters(self):
|
|
@@ -221,32 +234,34 @@ class BasicExecutor(ABC):
|
|
|
221
234
|
summary[cur_key] = cur_child_dict[cur_key]
|
|
222
235
|
return summary
|
|
223
236
|
|
|
224
|
-
def execute(self):
|
|
237
|
+
def execute(self, show_discarded=False):
|
|
225
238
|
"""
|
|
226
239
|
Executes the whole branch
|
|
227
240
|
"""
|
|
228
241
|
start_time = time.perf_counter()
|
|
229
|
-
self._prepare_execution()
|
|
242
|
+
self._prepare_execution(show_discarded=show_discarded)
|
|
230
243
|
|
|
231
244
|
try:
|
|
232
245
|
try:
|
|
233
|
-
self.
|
|
234
|
-
|
|
246
|
+
if self.has_runnable_tests():
|
|
247
|
+
self.fixture_manager.enter(self)
|
|
248
|
+
self.construct_result.set_result(ResultState.SUCCESS)
|
|
235
249
|
|
|
236
|
-
self._body_execution()
|
|
250
|
+
self._body_execution(show_discarded=show_discarded)
|
|
237
251
|
except Exception as exc:
|
|
238
252
|
# this has to be a construction fixture error
|
|
239
253
|
traceback.print_exception(*sys.exc_info())
|
|
240
254
|
self.construct_result.set_result(ResultState.ERROR, exc)
|
|
241
255
|
finally:
|
|
242
|
-
if self.
|
|
243
|
-
self.fixture_manager.
|
|
244
|
-
|
|
256
|
+
if self.has_runnable_tests():
|
|
257
|
+
if self.fixture_manager.is_allowed_to_leave(self):
|
|
258
|
+
self.fixture_manager.leave(self)
|
|
259
|
+
self.teardown_result.set_result(ResultState.SUCCESS)
|
|
245
260
|
except Exception as exc:
|
|
246
261
|
# this has to be a teardown fixture error
|
|
247
262
|
traceback.print_exception(*sys.exc_info())
|
|
248
263
|
self.teardown_result.set_result(ResultState.ERROR, exc)
|
|
249
264
|
|
|
250
|
-
self._cleanup_execution()
|
|
265
|
+
self._cleanup_execution(show_discarded=show_discarded)
|
|
251
266
|
|
|
252
267
|
self.execution_time_sec = time.perf_counter() - start_time
|
|
@@ -18,6 +18,7 @@ class ExecutorTree(BasicExecutor):
|
|
|
18
18
|
"""
|
|
19
19
|
This class is the root object of the executor tree structure
|
|
20
20
|
"""
|
|
21
|
+
LINE_LENGTH = 120
|
|
21
22
|
|
|
22
23
|
def __init__(self, fixture_manager: FixtureManager):
|
|
23
24
|
super().__init__()
|
|
@@ -35,18 +36,13 @@ class ExecutorTree(BasicExecutor):
|
|
|
35
36
|
|
|
36
37
|
@property
|
|
37
38
|
def all_child_executors(self) -> List[BasicExecutor]:
|
|
38
|
-
return self.
|
|
39
|
+
return self._setup_executors
|
|
39
40
|
|
|
40
41
|
@property
|
|
41
42
|
def base_instance(self) -> object:
|
|
42
43
|
"""returns None because this element is a ExecutorTree"""
|
|
43
44
|
return None
|
|
44
45
|
|
|
45
|
-
@property
|
|
46
|
-
def setup_executors(self) -> List[SetupExecutor]:
|
|
47
|
-
"""returns all setup executors of this tree"""
|
|
48
|
-
return self._setup_executors
|
|
49
|
-
|
|
50
46
|
@property
|
|
51
47
|
def fixture_manager(self) -> FixtureManager:
|
|
52
48
|
"""returns the fixture manager of this tree"""
|
|
@@ -58,13 +54,13 @@ class ExecutorTree(BasicExecutor):
|
|
|
58
54
|
|
|
59
55
|
# ---------------------------------- PROTECTED METHODS -------------------------------------------------------------
|
|
60
56
|
|
|
61
|
-
def _prepare_execution(self):
|
|
57
|
+
def _prepare_execution(self, show_discarded):
|
|
62
58
|
pass
|
|
63
59
|
|
|
64
|
-
def _body_execution(self):
|
|
65
|
-
for cur_setup_executor in self.
|
|
66
|
-
if cur_setup_executor.
|
|
67
|
-
cur_setup_executor.execute()
|
|
60
|
+
def _body_execution(self, show_discarded):
|
|
61
|
+
for cur_setup_executor in self.get_setup_executors():
|
|
62
|
+
if cur_setup_executor.has_runnable_tests(consider_discarded_too=show_discarded):
|
|
63
|
+
cur_setup_executor.execute(show_discarded=show_discarded)
|
|
68
64
|
elif cur_setup_executor.prev_mark == PreviousExecutorMark.SKIP:
|
|
69
65
|
cur_setup_executor.set_result_for_whole_branch(ResultState.SKIP)
|
|
70
66
|
elif cur_setup_executor.prev_mark == PreviousExecutorMark.COVERED_BY:
|
|
@@ -72,27 +68,31 @@ class ExecutorTree(BasicExecutor):
|
|
|
72
68
|
else:
|
|
73
69
|
cur_setup_executor.set_result_for_whole_branch(ResultState.NOT_RUN)
|
|
74
70
|
|
|
75
|
-
def _cleanup_execution(self):
|
|
71
|
+
def _cleanup_execution(self, show_discarded):
|
|
76
72
|
pass
|
|
77
73
|
|
|
78
74
|
# ---------------------------------- METHODS -----------------------------------------------------------------------
|
|
79
75
|
|
|
76
|
+
def get_setup_executors(self) -> List[SetupExecutor]:
|
|
77
|
+
"""returns all setup executors of this tree"""
|
|
78
|
+
return self._setup_executors
|
|
79
|
+
|
|
80
80
|
def get_all_scenario_executors(self) -> List[ScenarioExecutor]:
|
|
81
81
|
"""
|
|
82
82
|
returns a list with all scenario executors
|
|
83
83
|
"""
|
|
84
84
|
all_scenario_executor = []
|
|
85
|
-
for cur_setup_executor in self.
|
|
86
|
-
all_scenario_executor += cur_setup_executor.
|
|
85
|
+
for cur_setup_executor in self.get_setup_executors():
|
|
86
|
+
all_scenario_executor += cur_setup_executor.get_scenario_executors()
|
|
87
87
|
return all_scenario_executor
|
|
88
88
|
|
|
89
|
-
def get_all_variation_executors(self) -> List[VariationExecutor]:
|
|
89
|
+
def get_all_variation_executors(self, return_discarded=False) -> List[VariationExecutor]:
|
|
90
90
|
"""
|
|
91
91
|
returns a list with all variation executors
|
|
92
92
|
"""
|
|
93
93
|
all_variation_executor = []
|
|
94
94
|
for cur_scenario_executor in self.get_all_scenario_executors():
|
|
95
|
-
all_variation_executor += cur_scenario_executor.
|
|
95
|
+
all_variation_executor += cur_scenario_executor.get_variation_executors(return_discarded=return_discarded)
|
|
96
96
|
return all_variation_executor
|
|
97
97
|
|
|
98
98
|
def get_all_testcase_executors(self) -> List[TestcaseExecutor]:
|
|
@@ -101,8 +101,8 @@ class ExecutorTree(BasicExecutor):
|
|
|
101
101
|
"""
|
|
102
102
|
all_testcase_executor = []
|
|
103
103
|
for cur_scenario_executor in self.get_all_scenario_executors():
|
|
104
|
-
for cur_variation_executor in cur_scenario_executor.
|
|
105
|
-
all_testcase_executor += cur_variation_executor.
|
|
104
|
+
for cur_variation_executor in cur_scenario_executor.get_variation_executors():
|
|
105
|
+
all_testcase_executor += cur_variation_executor.get_testcase_executors()
|
|
106
106
|
return all_testcase_executor
|
|
107
107
|
|
|
108
108
|
def add_setup_executor(self, setup_executor: SetupExecutor):
|
|
@@ -129,35 +129,35 @@ class ExecutorTree(BasicExecutor):
|
|
|
129
129
|
# can not find some
|
|
130
130
|
return None
|
|
131
131
|
|
|
132
|
-
def cleanup_empty_executor_branches(self):
|
|
132
|
+
def cleanup_empty_executor_branches(self, consider_discarded=False):
|
|
133
133
|
to_remove_executor = []
|
|
134
|
-
for cur_setup_executor in self.
|
|
135
|
-
cur_setup_executor.cleanup_empty_executor_branches()
|
|
136
|
-
if len(cur_setup_executor.
|
|
134
|
+
for cur_setup_executor in self.get_setup_executors():
|
|
135
|
+
cur_setup_executor.cleanup_empty_executor_branches(consider_discarded=consider_discarded)
|
|
136
|
+
if len(cur_setup_executor.get_scenario_executors()) == 0:
|
|
137
137
|
# remove this whole executor because it has no children anymore
|
|
138
138
|
to_remove_executor.append(cur_setup_executor)
|
|
139
139
|
for cur_setup_executor in to_remove_executor:
|
|
140
140
|
self._setup_executors.remove(cur_setup_executor)
|
|
141
141
|
|
|
142
|
-
def execute(self) -> None:
|
|
142
|
+
def execute(self, show_discarded=False) -> None:
|
|
143
143
|
"""
|
|
144
144
|
This method executes this branch of the tree
|
|
145
145
|
"""
|
|
146
146
|
start_text = "START TESTSESSION"
|
|
147
147
|
end_text = "FINISH TESTSESSION"
|
|
148
|
-
line_length = 120
|
|
149
148
|
|
|
150
149
|
def print_line(text):
|
|
151
|
-
full_text = int((
|
|
152
|
-
full_text += "=" * (
|
|
150
|
+
full_text = int((self.LINE_LENGTH - (len(start_text) + 2)) / 2) * "=" + " " + text + " "
|
|
151
|
+
full_text += "=" * (self.LINE_LENGTH - len(full_text))
|
|
153
152
|
print(full_text)
|
|
154
153
|
|
|
155
154
|
print_line(start_text)
|
|
156
155
|
# check if there exists runnable elements
|
|
157
|
-
runnables = [cur_exec.
|
|
156
|
+
runnables = [cur_exec.has_runnable_tests(consider_discarded_too=show_discarded)
|
|
157
|
+
for cur_exec in self.get_setup_executors()]
|
|
158
158
|
one_or_more_runnable_setups = None if len(runnables) == 0 else max(runnables)
|
|
159
159
|
if one_or_more_runnable_setups:
|
|
160
|
-
super().execute()
|
|
160
|
+
super().execute(show_discarded=show_discarded)
|
|
161
161
|
else:
|
|
162
162
|
print("NO EXECUTABLE SETUPS/SCENARIOS FOUND")
|
|
163
163
|
print_line(end_text)
|
|
@@ -171,19 +171,32 @@ class ExecutorTree(BasicExecutor):
|
|
|
171
171
|
print(f"TOTAL {cur_key.value}: {cur_val}", end="")
|
|
172
172
|
print("")
|
|
173
173
|
|
|
174
|
-
def print_tree(self) -> None:
|
|
174
|
+
def print_tree(self, show_discarded=False) -> None:
|
|
175
175
|
"""this method is an auxiliary method which outputs the entire tree"""
|
|
176
176
|
print("RESOLVING OVERVIEW", end="\n\n")
|
|
177
|
-
for cur_setup_executor in self.
|
|
178
|
-
for cur_scenario_executor in cur_setup_executor.
|
|
179
|
-
for cur_variation_executor in cur_scenario_executor.
|
|
180
|
-
|
|
177
|
+
for cur_setup_executor in self.get_setup_executors():
|
|
178
|
+
for cur_scenario_executor in cur_setup_executor.get_scenario_executors():
|
|
179
|
+
for cur_variation_executor in cur_scenario_executor.get_variation_executors(
|
|
180
|
+
return_discarded=show_discarded):
|
|
181
|
+
applicable = cur_variation_executor.prev_mark != PreviousExecutorMark.DISCARDED
|
|
182
|
+
start_char = '+' if applicable else 'X'
|
|
183
|
+
print(start_char * self.LINE_LENGTH)
|
|
184
|
+
applicability_str = "[APPLICABLE]" if applicable else "[DISCARDED] "
|
|
185
|
+
print(f"{start_char} {applicability_str} Scenario "
|
|
186
|
+
f"`{cur_scenario_executor.base_scenario_class.__class__.__qualname__}` <-> "
|
|
181
187
|
f"Setup `{cur_setup_executor.base_setup_class.__class__.__qualname__}`")
|
|
182
188
|
mapping_printings = {}
|
|
183
189
|
for cur_scenario_device, cur_setup_device in cur_variation_executor.base_device_mapping.items():
|
|
184
190
|
mapping_printings[f" {cur_scenario_device.__qualname__}"] = str(cur_setup_device.__qualname__)
|
|
185
191
|
max_len = max(len(cur_elem) for cur_elem in mapping_printings.keys())
|
|
186
192
|
for cur_key, cur_val in mapping_printings.items():
|
|
187
|
-
print(("{:<" + str(max_len) + "} = {}").format(cur_key, cur_val))
|
|
188
|
-
for cur_testcase_excutor in cur_variation_executor.
|
|
189
|
-
print(f"
|
|
193
|
+
print(("{} {:<" + str(max_len) + "} = {}").format(start_char, cur_key, cur_val))
|
|
194
|
+
for cur_testcase_excutor in cur_variation_executor.get_testcase_executors():
|
|
195
|
+
print(f"{start_char} -> Testcase<"
|
|
196
|
+
f"{cur_testcase_excutor.base_testcase_callable.__qualname__}>")
|
|
197
|
+
if cur_variation_executor.prev_mark == PreviousExecutorMark.DISCARDED:
|
|
198
|
+
print(f"{start_char}")
|
|
199
|
+
print(f"{start_char} DISCARDED BECAUSE "
|
|
200
|
+
f"`{cur_variation_executor.not_applicable_variation_exc.args[0]}`")
|
|
201
|
+
print(('+' if applicable else 'X') * self.LINE_LENGTH)
|
|
202
|
+
print('')
|
|
@@ -46,7 +46,7 @@ class ScenarioExecutor(BasicExecutor):
|
|
|
46
46
|
|
|
47
47
|
@property
|
|
48
48
|
def all_child_executors(self) -> List[VariationExecutor]:
|
|
49
|
-
return self.
|
|
49
|
+
return self._variation_executors
|
|
50
50
|
|
|
51
51
|
@property
|
|
52
52
|
def parent_executor(self) -> SetupExecutor:
|
|
@@ -64,11 +64,6 @@ class ScenarioExecutor(BasicExecutor):
|
|
|
64
64
|
"""returns the :class:`Scenario` class that belongs to this executor"""
|
|
65
65
|
return self._base_scenario_class
|
|
66
66
|
|
|
67
|
-
@property
|
|
68
|
-
def variation_executors(self) -> List[VariationExecutor]:
|
|
69
|
-
"""returns all variation executors that are child executor of this scenario executor"""
|
|
70
|
-
return self._variation_executors
|
|
71
|
-
|
|
72
67
|
@property
|
|
73
68
|
def fixture_manager(self) -> FixtureManager:
|
|
74
69
|
"""returns the current active fixture manager that belongs to this scenario executor"""
|
|
@@ -91,13 +86,13 @@ class ScenarioExecutor(BasicExecutor):
|
|
|
91
86
|
|
|
92
87
|
# ---------------------------------- PROTECTED METHODS -------------------------------------------------------------
|
|
93
88
|
|
|
94
|
-
def _prepare_execution(self):
|
|
89
|
+
def _prepare_execution(self, show_discarded):
|
|
95
90
|
print(f" SCENARIO {self.base_scenario_class.__class__.__name__}")
|
|
96
91
|
|
|
97
|
-
def _body_execution(self):
|
|
98
|
-
for cur_variation_executor in self.
|
|
99
|
-
if cur_variation_executor.
|
|
100
|
-
cur_variation_executor.execute()
|
|
92
|
+
def _body_execution(self, show_discarded):
|
|
93
|
+
for cur_variation_executor in self.get_variation_executors(return_discarded=show_discarded):
|
|
94
|
+
if cur_variation_executor.has_runnable_tests(show_discarded):
|
|
95
|
+
cur_variation_executor.execute(show_discarded=show_discarded)
|
|
101
96
|
elif cur_variation_executor.prev_mark == PreviousExecutorMark.SKIP:
|
|
102
97
|
cur_variation_executor.set_result_for_whole_branch(ResultState.SKIP)
|
|
103
98
|
elif cur_variation_executor.prev_mark == PreviousExecutorMark.COVERED_BY:
|
|
@@ -105,18 +100,29 @@ class ScenarioExecutor(BasicExecutor):
|
|
|
105
100
|
else:
|
|
106
101
|
cur_variation_executor.set_result_for_whole_branch(ResultState.NOT_RUN)
|
|
107
102
|
|
|
108
|
-
def _cleanup_execution(self):
|
|
103
|
+
def _cleanup_execution(self, show_discarded):
|
|
109
104
|
pass
|
|
110
105
|
|
|
111
106
|
# ---------------------------------- METHODS -----------------------------------------------------------------------
|
|
112
107
|
|
|
113
|
-
def
|
|
108
|
+
def get_variation_executors(self, return_discarded=False) -> List[VariationExecutor]:
|
|
109
|
+
"""
|
|
110
|
+
:param return_discarded: True if the method should return discarded variations too
|
|
111
|
+
|
|
112
|
+
:return: returns all variation executors that are child executor of this scenario executor
|
|
113
|
+
"""
|
|
114
|
+
if not return_discarded:
|
|
115
|
+
return [cur_executor for cur_executor in self._variation_executors
|
|
116
|
+
if cur_executor.prev_mark != PreviousExecutorMark.DISCARDED]
|
|
117
|
+
return self._variation_executors
|
|
118
|
+
|
|
119
|
+
def cleanup_empty_executor_branches(self, consider_discarded=False):
|
|
114
120
|
"""
|
|
115
121
|
This method removes all sub executors that are empty and not relevant anymore.
|
|
116
122
|
"""
|
|
117
123
|
to_remove_executor = []
|
|
118
|
-
for cur_variation_executor in self.
|
|
119
|
-
if len(cur_variation_executor.
|
|
124
|
+
for cur_variation_executor in self.get_variation_executors(return_discarded=consider_discarded):
|
|
125
|
+
if len(cur_variation_executor.get_testcase_executors()) == 0:
|
|
120
126
|
# remove this whole executor because it has no children anymore
|
|
121
127
|
to_remove_executor.append(cur_variation_executor)
|
|
122
128
|
for cur_variation_executor in to_remove_executor:
|
|
@@ -42,7 +42,7 @@ class SetupExecutor(BasicExecutor):
|
|
|
42
42
|
|
|
43
43
|
@property
|
|
44
44
|
def all_child_executors(self) -> List[ScenarioExecutor]:
|
|
45
|
-
return self.
|
|
45
|
+
return self._scenario_executors
|
|
46
46
|
|
|
47
47
|
@property
|
|
48
48
|
def parent_executor(self) -> ExecutorTree:
|
|
@@ -58,11 +58,6 @@ class SetupExecutor(BasicExecutor):
|
|
|
58
58
|
"""returns the base :class:`Setup` that belongs to this executor"""
|
|
59
59
|
return self._base_setup_class
|
|
60
60
|
|
|
61
|
-
@property
|
|
62
|
-
def scenario_executors(self) -> List[ScenarioExecutor]:
|
|
63
|
-
"""returns a list with all scenario executors that belongs to this setup executor"""
|
|
64
|
-
return self._scenario_executors
|
|
65
|
-
|
|
66
61
|
@property
|
|
67
62
|
def fixture_manager(self) -> FixtureManager:
|
|
68
63
|
"""returns the current active fixture manager for this executor"""
|
|
@@ -70,13 +65,13 @@ class SetupExecutor(BasicExecutor):
|
|
|
70
65
|
|
|
71
66
|
# ---------------------------------- PROTECTED METHODS -------------------------------------------------------------
|
|
72
67
|
|
|
73
|
-
def _prepare_execution(self):
|
|
68
|
+
def _prepare_execution(self, show_discarded):
|
|
74
69
|
print(f"SETUP {self.base_setup_class.__class__.__name__}")
|
|
75
70
|
|
|
76
|
-
def _body_execution(self):
|
|
77
|
-
for cur_scenario_executor in self.
|
|
78
|
-
if cur_scenario_executor.
|
|
79
|
-
cur_scenario_executor.execute()
|
|
71
|
+
def _body_execution(self, show_discarded):
|
|
72
|
+
for cur_scenario_executor in self.get_scenario_executors():
|
|
73
|
+
if cur_scenario_executor.has_runnable_tests(consider_discarded_too=show_discarded):
|
|
74
|
+
cur_scenario_executor.execute(show_discarded=show_discarded)
|
|
80
75
|
elif cur_scenario_executor.prev_mark == PreviousExecutorMark.SKIP:
|
|
81
76
|
cur_scenario_executor.set_result_for_whole_branch(ResultState.SKIP)
|
|
82
77
|
elif cur_scenario_executor.prev_mark == PreviousExecutorMark.COVERED_BY:
|
|
@@ -84,16 +79,20 @@ class SetupExecutor(BasicExecutor):
|
|
|
84
79
|
else:
|
|
85
80
|
cur_scenario_executor.set_result_for_whole_branch(ResultState.NOT_RUN)
|
|
86
81
|
|
|
87
|
-
def _cleanup_execution(self):
|
|
82
|
+
def _cleanup_execution(self, show_discarded):
|
|
88
83
|
pass
|
|
89
84
|
|
|
90
85
|
# ---------------------------------- METHODS -----------------------------------------------------------------------
|
|
91
86
|
|
|
92
|
-
def
|
|
87
|
+
def get_scenario_executors(self) -> List[ScenarioExecutor]:
|
|
88
|
+
"""returns a list with all scenario executors that belongs to this setup executor"""
|
|
89
|
+
return self._scenario_executors
|
|
90
|
+
|
|
91
|
+
def cleanup_empty_executor_branches(self, consider_discarded=False):
|
|
93
92
|
to_remove_executor = []
|
|
94
|
-
for cur_scenario_executor in self.
|
|
95
|
-
cur_scenario_executor.cleanup_empty_executor_branches()
|
|
96
|
-
if len(cur_scenario_executor.
|
|
93
|
+
for cur_scenario_executor in self.get_scenario_executors():
|
|
94
|
+
cur_scenario_executor.cleanup_empty_executor_branches(consider_discarded=consider_discarded)
|
|
95
|
+
if len(cur_scenario_executor.get_variation_executors(return_discarded=consider_discarded)) == 0:
|
|
97
96
|
# remove this whole executor because it has no children anymore
|
|
98
97
|
to_remove_executor.append(cur_scenario_executor)
|
|
99
98
|
for cur_scenario_executor in to_remove_executor:
|
|
@@ -7,7 +7,6 @@ import traceback
|
|
|
7
7
|
from _balder.utils import inspect_method
|
|
8
8
|
from _balder.testresult import ResultState, TestcaseResult
|
|
9
9
|
from _balder.executor.basic_executor import BasicExecutor
|
|
10
|
-
from _balder.previous_executor_mark import PreviousExecutorMark
|
|
11
10
|
|
|
12
11
|
if TYPE_CHECKING:
|
|
13
12
|
from _balder.executor.variation_executor import VariationExecutor
|
|
@@ -76,7 +75,7 @@ class TestcaseExecutor(BasicExecutor):
|
|
|
76
75
|
|
|
77
76
|
# ---------------------------------- PROTECTED METHODS -------------------------------------------------------------
|
|
78
77
|
|
|
79
|
-
def _prepare_execution(self):
|
|
78
|
+
def _prepare_execution(self, show_discarded):
|
|
80
79
|
print(f" TEST {self.base_testcase_callable.__qualname__} ", end='')
|
|
81
80
|
if self.should_be_skipped():
|
|
82
81
|
self.body_result.set_result(ResultState.SKIP)
|
|
@@ -84,7 +83,7 @@ class TestcaseExecutor(BasicExecutor):
|
|
|
84
83
|
print("[S]")
|
|
85
84
|
return
|
|
86
85
|
|
|
87
|
-
def _body_execution(self):
|
|
86
|
+
def _body_execution(self, show_discarded):
|
|
88
87
|
start_time = time.perf_counter()
|
|
89
88
|
try:
|
|
90
89
|
_, func_type = inspect_method(self.base_testcase_callable)
|
|
@@ -109,14 +108,11 @@ class TestcaseExecutor(BasicExecutor):
|
|
|
109
108
|
self.body_result.set_result(ResultState.FAILURE, exc)
|
|
110
109
|
self.test_execution_time_sec = time.perf_counter() - start_time
|
|
111
110
|
|
|
112
|
-
def _cleanup_execution(self):
|
|
111
|
+
def _cleanup_execution(self, show_discarded):
|
|
113
112
|
print(f"[{self.body_result.get_result_as_char()}]")
|
|
114
113
|
|
|
115
114
|
# ---------------------------------- METHODS -----------------------------------------------------------------------
|
|
116
115
|
|
|
117
|
-
def has_runnable_elements(self) -> bool:
|
|
118
|
-
return self.prev_mark == PreviousExecutorMark.RUNNABLE
|
|
119
|
-
|
|
120
116
|
def should_run(self):
|
|
121
117
|
"""returns true if the testcase should be executed (defined in scenario)"""
|
|
122
118
|
if self.base_testcase_callable in self.parent_executor.parent_executor.all_run_tests:
|
|
@@ -135,7 +131,7 @@ class TestcaseExecutor(BasicExecutor):
|
|
|
135
131
|
return True
|
|
136
132
|
return False
|
|
137
133
|
|
|
138
|
-
def cleanup_empty_executor_branches(self):
|
|
134
|
+
def cleanup_empty_executor_branches(self, consider_discarded=False):
|
|
139
135
|
"""
|
|
140
136
|
This method searches the whole tree and removes branches where an executor item has no own children. It can
|
|
141
137
|
remove these branches, because they have no valid matchings.
|