@@ -129,40 +129,19 @@ def run_json_tests(self, effects: dict, estimators: dict, f_flag: bool = False,
129
129
if "skip" in test and test ["skip" ]:
130
130
continue
131
131
test ["estimator" ] = estimators [test ["estimator" ]]
132
- if "mutations" in test :
132
+ # If we have specified concrete control and treatment value
133
+ if "mutations" not in test :
134
+ failed , msg = self ._run_concrete_metamorphic_test ()
135
+ # If we have a variable to mutate
136
+ else :
133
137
if test ["estimate_type" ] == "coefficient" :
134
138
failed , msg = self ._run_coefficient_test (test = test , f_flag = f_flag , effects = effects )
135
139
else :
136
- failed , msg = self ._run_ate_test (test = test , f_flag = f_flag , effects = effects , mutates = mutates )
137
- self ._append_to_file (msg , logging .INFO )
138
- else :
139
- outcome_variable = next (
140
- iter (test ["expected_effect" ])
141
- ) # Take first key from dictionary of expected effect
142
- base_test_case = BaseTestCase (
143
- treatment_variable = self .variables ["inputs" ][test ["treatment_variable" ]],
144
- outcome_variable = self .variables ["outputs" ][outcome_variable ],
145
- )
146
-
147
- causal_test_case = CausalTestCase (
148
- base_test_case = base_test_case ,
149
- expected_causal_effect = effects [test ["expected_effect" ][outcome_variable ]],
150
- control_value = test ["control_value" ],
151
- treatment_value = test ["treatment_value" ],
152
- estimate_type = test ["estimate_type" ],
153
- )
154
- failed , _ = self ._execute_test_case (causal_test_case = causal_test_case , test = test , f_flag = f_flag )
155
-
156
- msg = (
157
- f"Executing concrete test: { test ['name' ]} \n "
158
- + f"treatment variable: { test ['treatment_variable' ]} \n "
159
- + f"outcome_variable = { outcome_variable } \n "
160
- + f"control value = { test ['control_value' ]} , treatment value = { test ['treatment_value' ]} \n "
161
- + f"Result: { 'FAILED' if failed else 'Passed' } "
162
- )
163
- self ._append_to_file (msg , logging .INFO )
140
+ failed , msg = self ._run_metamorphic_tests (
141
+ test = test , f_flag = f_flag , effects = effects , mutates = mutates
142
+ )
164
143
test ["failed" ] = failed
165
- # print( msg)
144
+ test [ "result" ] = msg
166
145
return self .test_plan ["tests" ]
167
146
168
147
def _run_coefficient_test (self , test : dict , f_flag : bool , effects : dict ):
@@ -194,9 +173,36 @@ def _run_coefficient_test(self, test: dict, f_flag: bool, effects: dict):
194
173
+ "==============\n "
195
174
+ f" Result: { 'FAILED' if failed else 'Passed' } "
196
175
)
176
+ self ._append_to_file (msg , logging .INFO )
177
+ return failed , result
178
+
179
+ def _run_concrete_metamorphic_test (self , test : dict , f_flag : bool , effects : dict , mutates : dict ):
180
+ outcome_variable = next (iter (test ["expected_effect" ])) # Take first key from dictionary of expected effect
181
+ base_test_case = BaseTestCase (
182
+ treatment_variable = self .variables ["inputs" ][test ["treatment_variable" ]],
183
+ outcome_variable = self .variables ["outputs" ][outcome_variable ],
184
+ )
185
+
186
+ causal_test_case = CausalTestCase (
187
+ base_test_case = base_test_case ,
188
+ expected_causal_effect = effects [test ["expected_effect" ][outcome_variable ]],
189
+ control_value = test ["control_value" ],
190
+ treatment_value = test ["treatment_value" ],
191
+ estimate_type = test ["estimate_type" ],
192
+ )
193
+ failed , msg = self ._execute_test_case (causal_test_case = causal_test_case , test = test , f_flag = f_flag )
194
+
195
+ msg = (
196
+ f"Executing concrete test: { test ['name' ]} \n "
197
+ + f"treatment variable: { test ['treatment_variable' ]} \n "
198
+ + f"outcome_variable = { outcome_variable } \n "
199
+ + f"control value = { test ['control_value' ]} , treatment value = { test ['treatment_value' ]} \n "
200
+ + f"Result: { 'FAILED' if failed else 'Passed' } "
201
+ )
202
+ self ._append_to_file (msg , logging .INFO )
197
203
return failed , msg
198
204
199
- def _run_ate_test (self , test : dict , f_flag : bool , effects : dict , mutates : dict ):
205
+ def _run_metamorphic_tests (self , test : dict , f_flag : bool , effects : dict , mutates : dict ):
200
206
"""Builds structures and runs test case for tests with an estimate_type of 'ate'.
201
207
202
208
:param test: Single JSON test definition stored in a mapping (dict)
@@ -228,6 +234,7 @@ def _run_ate_test(self, test: dict, f_flag: bool, effects: dict, mutates: dict):
228
234
+ f" Number of concrete tests for test case: { str (len (concrete_tests ))} \n "
229
235
+ f" { failures } /{ len (concrete_tests )} failed for { test ['name' ]} "
230
236
)
237
+ self ._append_to_file (msg , logging .INFO )
231
238
return failures , msg
232
239
233
240
def _execute_tests (self , concrete_tests , test , f_flag ):
@@ -269,10 +276,11 @@ def _execute_test_case(
269
276
test_passes = causal_test_case .expected_causal_effect .apply (causal_test_result )
270
277
271
278
if "coverage" in test and test ["coverage" ]:
272
- adequacy = DataAdequacy (causal_test_case , causal_test_engine , estimation_model )
273
- effect_estimate , ci_low , ci_high , outcomes = adequacy .measure_adequacy (100 )
274
- self ._append_to_file (f"KURTOSIS: { effect_estimate .mean ()} " , logging .INFO )
275
- self ._append_to_file (f"PASSING: { sum (outcomes )} /{ len (outcomes )} " , logging .INFO )
279
+ adequacy_metric = DataAdequacy (causal_test_case , causal_test_engine , estimation_model )
280
+ adequacy_metric .measure_adequacy ()
281
+ # self._append_to_file(f"KURTOSIS: {effect_estimate.mean()}", logging.INFO)
282
+ # self._append_to_file(f"PASSING: {sum(outcomes)}/{len(outcomes)}", logging.INFO)
283
+ causal_test_result .adequacy = adequacy_metric
276
284
277
285
if causal_test_result .ci_low () is not None and causal_test_result .ci_high () is not None :
278
286
result_string = (
0 commit comments