21
21
from causal_testing .specification .scenario import Scenario
22
22
from causal_testing .specification .variable import Input , Meta , Output
23
23
from causal_testing .testing .causal_test_case import CausalTestCase
24
+ from causal_testing .testing .causal_test_result import CausalTestResult
24
25
from causal_testing .testing .causal_test_engine import CausalTestEngine
25
26
from causal_testing .testing .estimators import Estimator
26
27
from causal_testing .testing .base_test_case import BaseTestCase
@@ -124,28 +125,29 @@ def run_json_tests(self, effects: dict, estimators: dict, f_flag: bool = False,
124
125
effect = test .get ("effect" , "direct" ),
125
126
)
126
127
assert len (test ["expected_effect" ]) == 1 , "Can only have one expected effect."
127
- concrete_tests = [
128
- CausalTestCase (
129
- base_test_case = base_test_case ,
130
- expected_causal_effect = next (
131
- effects [effect ] for variable , effect in test ["expected_effect" ].items ()
132
- ),
133
- estimate_type = "coefficient" ,
134
- effect_modifier_configuration = {
135
- self .scenario .variables [v ] for v in test .get ("effect_modifiers" , [])
136
- },
137
- )
138
- ]
139
- failures = self ._execute_tests (concrete_tests , test , f_flag )
128
+ causal_test_case = CausalTestCase (
129
+ base_test_case = base_test_case ,
130
+ expected_causal_effect = next (
131
+ effects [effect ] for variable , effect in test ["expected_effect" ].items ()
132
+ ),
133
+ estimate_type = "coefficient" ,
134
+ effect_modifier_configuration = {
135
+ self .scenario .variables [v ] for v in test .get ("effect_modifiers" , [])
136
+ },
137
+ )
138
+ result = self ._execute_test_case (causal_test_case = causal_test_case , test = test , f_flag = f_flag )
140
139
msg = (
141
140
f"Executing test: { test ['name' ]} \n "
142
- + f" { concrete_tests [0 ]} \n "
143
- + f" { failures } /{ len (concrete_tests )} failed for { test ['name' ]} "
141
+ + f" { causal_test_case } \n "
142
+ + " "
143
+ + ("\n " ).join (str (result [1 ]).split ("\n " ))
144
+ + "==============\n "
145
+ + f" Result: { 'FAILED' if result [0 ] else 'Passed' } "
144
146
)
145
147
else :
146
148
abstract_test = self ._create_abstract_test_case (test , mutates , effects )
147
- concrete_tests , dummy = abstract_test .generate_concrete_tests (5 , 0.05 )
148
- failures = self ._execute_tests (concrete_tests , test , f_flag )
149
+ concrete_tests , _ = abstract_test .generate_concrete_tests (5 , 0.05 )
150
+ failures , _ = self ._execute_tests (concrete_tests , test , f_flag )
149
151
150
152
msg = (
151
153
f"Executing test: { test ['name' ]} \n "
@@ -173,29 +175,28 @@ def run_json_tests(self, effects: dict, estimators: dict, f_flag: bool = False,
173
175
treatment_value = test ["treatment_value" ],
174
176
estimate_type = test ["estimate_type" ],
175
177
)
176
- if self ._execute_test_case (causal_test_case = causal_test_case , test = test , f_flag = f_flag ):
177
- result = "failed"
178
- else :
179
- result = "passed"
178
+ failed , _ = self ._execute_test_case (causal_test_case = causal_test_case , test = test , f_flag = f_flag )
180
179
181
180
msg = (
182
181
f"Executing concrete test: { test ['name' ]} \n "
183
182
+ f"treatment variable: { test ['treatment_variable' ]} \n "
184
183
+ f"outcome_variable = { outcome_variable } \n "
185
184
+ f"control value = { test ['control_value' ]} , treatment value = { test ['treatment_value' ]} \n "
186
- + f"result - { result } "
185
+ + f"Result: { 'FAILED' if failed else 'Passed' } "
187
186
)
188
187
self ._append_to_file (msg , logging .INFO )
189
188
190
189
def _execute_tests (self , concrete_tests , test , f_flag ):
191
190
failures = 0
191
+ details = []
192
192
if "formula" in test :
193
193
self ._append_to_file (f"Estimator formula used for test: { test ['formula' ]} " )
194
194
for concrete_test in concrete_tests :
195
- failed = self ._execute_test_case (concrete_test , test , f_flag )
195
+ failed , result = self ._execute_test_case (concrete_test , test , f_flag )
196
+ details .append (result )
196
197
if failed :
197
198
failures += 1
198
- return failures
199
+ return failures , details
199
200
200
201
def _json_parse (self ):
201
202
"""Parse a JSON input file into inputs, outputs, metas and a test plan"""
@@ -213,7 +214,9 @@ def _populate_metas(self):
213
214
for meta in self .scenario .variables_of_type (Meta ):
214
215
meta .populate (self .data )
215
216
216
- def _execute_test_case (self , causal_test_case : CausalTestCase , test : Iterable [Mapping ], f_flag : bool ) -> bool :
217
+ def _execute_test_case (
218
+ self , causal_test_case : CausalTestCase , test : Iterable [Mapping ], f_flag : bool
219
+ ) -> (bool , CausalTestResult ):
217
220
"""Executes a singular test case, prints the results and returns the test case result
218
221
:param causal_test_case: The concrete test case to be executed
219
222
:param test: Single JSON test definition stored in a mapping (dict)
@@ -249,7 +252,7 @@ def _execute_test_case(self, causal_test_case: CausalTestCase, test: Iterable[Ma
249
252
)
250
253
failed = True
251
254
logger .warning (" FAILED- expected %s, got %s" , causal_test_case .expected_causal_effect , result_string )
252
- return failed
255
+ return failed , causal_test_result
253
256
254
257
def _setup_test (
255
258
self , causal_test_case : CausalTestCase , test : Mapping , conditions : list [str ] = None
0 commit comments