@@ -89,7 +89,7 @@ def patch_scenario_with_accuracy(context, scenario, data_key_suffix, accuracy=0.
8989 """
9090 def scenario_run_with_accuracy (context , scenario_run , scenario , * args , ** kwargs ):
9191 # Execute the scenario multiple times and count passed executions
92- passed_executions = 0
92+ passed_executions = skipped_executions = 0
9393 # Copy scenario steps to avoid modifications in each execution, especially when using behave variables
9494 # transformation, like map_param and replace_param methods
9595 orig_steps = deepcopy (scenario .steps )
@@ -99,30 +99,50 @@ def scenario_run_with_accuracy(context, scenario_run, scenario, *args, **kwargs)
9999 # Restore original steps before each execution
100100 scenario .steps = deepcopy (orig_steps )
101101 if not scenario_run (* args , ** kwargs ):
102- passed_executions += 1
103- status = "PASSED"
102+ if scenario .status == Status .skipped :
103+ skipped_executions += 1
104+ status = "SKIPPED"
105+ else :
106+ passed_executions += 1
107+ status = "PASSED"
104108 else :
105109 status = "FAILED"
106110 print (f"ACCURACY SCENARIO { status } : execution { execution + 1 } /{ executions } " )
107111 context .logger .info (f"Accuracy scenario execution { status } ({ execution + 1 } /{ executions } )" )
108112
109- # Calculate scenario accuracy
110- scenario_accuracy = passed_executions / executions
111- has_passed = scenario_accuracy >= accuracy
112- final_status = 'PASSED' if has_passed else 'FAILED'
113- print (f"\n ACCURACY SCENARIO { final_status } : { executions } executions,"
114- f" accuracy { scenario_accuracy } >= { accuracy } " )
115- final_message = (f"Accuracy scenario { final_status } after { executions } executions with"
116- f" accuracy { scenario_accuracy } >= { accuracy } " )
117-
118- # Set final scenario status
119- if has_passed :
120- context .logger .info (final_message )
121- scenario .set_status (Status .passed )
113+
114+ if executions == skipped_executions :
115+ run_response = False # Run method returns true only when failed
116+ context .logger .info ("All accuracy scenario executions are skipped" )
122117 else :
123- context .logger .error (final_message )
124- scenario .set_status (Status .failed )
125- return not has_passed # Run method returns true when failed
118+ # Calculate scenario accuracy
119+ scenario_accuracy = passed_executions / (executions - skipped_executions )
120+ has_passed = scenario_accuracy >= accuracy
121+ run_response = not has_passed # Run method returns true only when failed
122+ final_status = 'PASSED' if has_passed else 'FAILED'
123+ print (f"\n ACCURACY SCENARIO { final_status } : { executions } executions,"
124+ f" accuracy { scenario_accuracy } >= { accuracy } " )
125+ final_message = (f"Accuracy scenario { final_status } after { executions } executions with"
126+ f" accuracy { scenario_accuracy } >= { accuracy } "
127+ f" ({ passed_executions } passed, { skipped_executions } skipped,"
128+ f" { executions - passed_executions - skipped_executions } failed)" )
129+
130+ # Set final scenario status
131+ if has_passed :
132+ context .logger .info (final_message )
133+ scenario .set_status (Status .passed )
134+ else :
135+ context .logger .error (final_message )
136+ scenario .set_status (Status .failed )
137+ scenario .exception = AssertionError (final_message )
138+
139+ # Clean accuracy execution data from context
140+ context .storage .pop ("accuracy_execution_data" , None )
141+ context .storage .pop ("accuracy_execution_index" , None )
142+
143+ after_accuracy_scenario (context , scenario )
144+
145+ return run_response
126146
127147 scenario_run = scenario .run
128148 scenario .run = functools .partial (scenario_run_with_accuracy , context , scenario_run , scenario )
@@ -190,3 +210,14 @@ def store_execution_data(context, execution, data_key_suffix):
190210 context .storage ["accuracy_execution_index" ] = execution
191211 context .logger .info (f"Stored accuracy data for execution { execution + 1 } in"
192212 f" accuracy_execution_data: { execution_data } " )
213+
214+
215+ def after_accuracy_scenario (context , scenario ):
216+ """Hook called after accuracy scenario execution.
217+ Monkey-patch this method to implement custom behavior after accuracy scenario execution, like calling Allure
218+ after_scenario method.
219+
220+ :param context: behave context
221+ :param scenario: behave scenario
222+ """
223+ pass
0 commit comments