@@ -911,3 +911,49 @@ def test_initial_portfolio_metrics(self, reqmock):
911911 text = '{"num": 1.0}' )
912912 f = OptimizationView (id = 'abc123' ).initial_metrics ()
913913 assert f .num == 1.0
914+
915+ sensitivity_text = """
916+ {"sensitivities": [
917+ {"normalized_interquartile_range": 0.25, "min": 0.0, "normalized_standard_deviation": 0.29,
918+ "initial_share": 0.18, "hist": { "0.05": 5, "0.1": 0, "0.15": 0, "0.2": 0, "0.25": 0, "0.3": 9, "0.35": 0,
919+ "0.4": 0, "0.45": 0, "0.5": 3, "0.55": 0, "0.6": 5, "0.65": 0, "0.7": 3, "0.75": 0, "0.8": 3, "0.85": 2,
920+ "0.9": 4, "0.95": 2, "1.0": 64}, "mean": 0.81, "max": 1.0, "ref_id": "layer2"
921+ },
922+ { "normalized_interquartile_range": 0.71, "min": 0.0, "normalized_standard_deviation": 0.35,
923+ "initial_share": 0.08, "hist": {"0.05": 36, "0.1": 0, "0.15": 8, "0.2": 1, "0.25": 1, "0.3": 3,
924+ "0.35": 2, "0.4": 3, "0.45": 0, "0.5": 0, "0.55": 8, "0.6": 0, "0.65": 12, "0.7": 0, "0.75": 1,
925+ "0.8": 10, "0.85": 0, "0.9": 7, "0.95": 0, "1.0": 8}, "mean": 0.37, "max": 1.0, "ref_id": "layer1" }
926+ ] } """
927+
928+ required_attributes = ['hist' , 'min' , 'max' , 'mean' , 'normalized_standard_deviation' ,
929+ 'normalized_interquartile_range' , 'ref_id' ]
930+
931+ @pytest .mark .parametrize ("get_string, candidates, expected_len" , [
932+ ('https://api/optimization_views/abc_id/sensitivity_analysis' , [], 2 ),
933+ ('https://api/optimization_views/abc_id/sensitivity_analysis?candidates=0,2,5' , [0 , 2 , 5 ], 2 ),
934+ ('https://api/optimization_views/abc_id/sensitivity_analysis?candidates=0,2,5' , [0 , 2 , 5 , 'a' , 1.1 , - 2 ], 2 )
935+ ])
936+ def test_sensitivity_analysis_with_candidates (self , reqmock , candidates , expected_len , get_string ):
937+ # list of candidates should be translated to the correct api request
938+ reqmock .get ('https://api/optimization_views/abc_id' ,
939+ status_code = 200 , text = '{"id":"abc_id"}' )
940+ ov = OptimizationView .retrieve ('abc_id' )
941+ reqmock .get (get_string ,
942+ status_code = 200 , text = TestOptimizationResource .sensitivity_text )
943+ r = ov .sensitivity_analysis (candidates = candidates )
944+ assert hasattr (r , 'sensitivities' )
945+ assert len (r .sensitivities ) == expected_len
946+ for i in range (len (r .sensitivities )):
947+ for attribute in TestOptimizationResource .required_attributes :
948+ assert hasattr (r .sensitivities [i ], attribute )
949+
950+ def test_sensitivity_analysis_empty (self , reqmock ):
951+ # result can be an empty list
952+ reqmock .get ('https://api/optimization_views/abc_id' ,
953+ status_code = 200 , text = '{"id":"abc_id"}' )
954+ ov = OptimizationView .retrieve ('abc_id' )
955+ reqmock .get ('https://api/optimization_views/abc_id/sensitivity_analysis' ,
956+ status_code = 200 , text = '{"sensitivities": []}' )
957+ r = ov .sensitivity_analysis ()
958+ assert hasattr (r , 'sensitivities' )
959+ assert len (r .sensitivities ) == 0
0 commit comments