diff --git a/src/topupopt/problems/esipp/blocks/prices.py b/src/topupopt/problems/esipp/blocks/prices.py
index 2af7aa3b810b0c280b2d1a2bbdf1397f37766448..097e9356cbb2541b84513690ea91fd50475fef8f 100644
--- a/src/topupopt/problems/esipp/blocks/prices.py
+++ b/src/topupopt/problems/esipp/blocks/prices.py
@@ -137,53 +137,54 @@ def price_other_block(
         # *********************************************************************
         
         # non-convex price functions
-        # TODO: fix the variables if the function is convex
-        # delta variables
-        b.var_active_segment_s = pyo.Var(b.set_S, within=pyo.Binary)
-        
-        # segments must be empty if the respective delta variable is zero
-        def rule_constr_empty_segment_if_delta_zero(b, s):
-            if len(b.set_S) == 1 or b.param_price_function_is_convex:
-                # single segment, skip
-                # convex, skip
-                return pyo.Constraint.Skip
-            return (
-                b.var_trans_flows_s[s] <= 
-                b.param_v_max_s[s]*b.var_active_segment_s[s]
+        if not b.param_price_function_is_convex:
+            
+            # delta variables
+            b.var_active_segment_s = pyo.Var(b.set_S, within=pyo.Binary)
+            
+            # segments must be empty if the respective delta variable is zero
+            def rule_constr_empty_segment_if_delta_zero(b, s):
+                if len(b.set_S) == 1 or b.param_price_function_is_convex:
+                    # single segment, skip
+                    # convex, skip
+                    return pyo.Constraint.Skip
+                return (
+                    b.var_trans_flows_s[s] <= 
+                    b.param_v_max_s[s]*b.var_active_segment_s[s]
+                    )
+            b.constr_empty_segment_if_delta_zero = pyo.Constraint(
+                b.set_S, rule=rule_constr_empty_segment_if_delta_zero
                 )
-        b.constr_empty_segment_if_delta_zero = pyo.Constraint(
-            b.set_S, rule=rule_constr_empty_segment_if_delta_zero
-            )
-        
-        # if delta var is one, previous ones must be one too
-        # if delta var is zero, the next ones must also be zero
-        def rule_constr_delta_summing_logic(b, s):
-            if s == len(b.set_S)-1 or b.param_price_function_is_convex:
-                # last segment, skip
-                # convex, skip
-                return pyo.Constraint.Skip
-            return (
-                b.var_active_segment_s[s] >= 
-                b.var_active_segment_s[s+1]
+            
+            # if delta var is one, previous ones must be one too
+            # if delta var is zero, the next ones must also be zero
+            def rule_constr_delta_summing_logic(b, s):
+                if s == len(b.set_S)-1 or b.param_price_function_is_convex:
+                    # last segment, skip
+                    # convex, skip
+                    return pyo.Constraint.Skip
+                return (
+                    b.var_active_segment_s[s] >= 
+                    b.var_active_segment_s[s+1]
+                    )
+            b.constr_delta_summing_logic = pyo.Constraint(
+                b.set_S, rule=rule_constr_delta_summing_logic
                 )
-        b.constr_delta_summing_logic = pyo.Constraint(
-            b.set_S, rule=rule_constr_delta_summing_logic
-            )
-        
-        # if a segment is not completely used, the next ones must remain empty
-        def rule_constr_fill_up_segment_before_next(b, s):
-            if s == len(b.set_S)-1 or b.param_price_function_is_convex:
-                # last segment, skip
-                # convex, skip
-                return pyo.Constraint.Skip
-            return (
-                b.var_trans_flows_s[s] >= 
-                b.var_active_segment_s[s+1]*
-                b.param_v_max_s[s]
+            
+            # if a segment is not completely used, the next ones must remain empty
+            def rule_constr_fill_up_segment_before_next(b, s):
+                if s == len(b.set_S)-1 or b.param_price_function_is_convex:
+                    # last segment, skip
+                    # convex, skip
+                    return pyo.Constraint.Skip
+                return (
+                    b.var_trans_flows_s[s] >= 
+                    b.var_active_segment_s[s+1]*
+                    b.param_v_max_s[s]
+                    )
+            b.constr_fill_up_segment_before_next = pyo.Constraint(
+                b.set_S, rule=rule_constr_fill_up_segment_before_next
                 )
-        b.constr_fill_up_segment_before_next = pyo.Constraint(
-            b.set_S, rule=rule_constr_fill_up_segment_before_next
-            )
         
         # *********************************************************************
         # ********************************************************************* 
diff --git a/tests/test_esipp.py b/tests/test_esipp.py
new file mode 100644
index 0000000000000000000000000000000000000000..1d74c881ef43c0e775fb53eff44d44d92ead0161
--- /dev/null
+++ b/tests/test_esipp.py
@@ -0,0 +1,224 @@
+# imports
+
+# local
+# import numpy as np
+# import networkx as nx
+from src.topupopt.problems.esipp.problem import InfrastructurePlanningProblem
+from src.topupopt.problems.esipp.network import Network
+from src.topupopt.problems.esipp.time import EconomicTimeFrame
+
+# *****************************************************************************
+# *****************************************************************************
+
+def build_solve_ipp(
+    solver: str = 'glpk',
+    solver_options: dict = None,
+    use_sos_arcs: bool = False,
+    arc_sos_weight_key: str = InfrastructurePlanningProblem.SOS1_ARC_WEIGHTS_NONE,
+    arc_use_real_variables_if_possible: bool = False,
+    use_sos_sense: bool = False,
+    sense_sos_weight_key: int = (
+        InfrastructurePlanningProblem.SOS1_SENSE_WEIGHT_NOMINAL_HIGHER
+    ),
+    sense_use_real_variables_if_possible: bool = False,
+    sense_use_arc_interfaces: bool = False,
+    perform_analysis: bool = False,
+    plot_results: bool = False,
+    print_solver_output: bool = False,
+    time_frame: EconomicTimeFrame = None,
+    networks: dict = None,
+    converters: dict = None,
+    static_losses_mode=None,
+    mandatory_arcs: list = None,
+    max_number_parallel_arcs: dict = None,
+    arc_groups_dict: dict = None,
+    init_aux_sets: bool = False,
+    # discount_rates: dict = None,
+    assessment_weights: dict = None,
+    simplify_problem: bool = False,
+    use_prices_block: bool = False
+):
+    
+    if type(assessment_weights) != dict:
+        assessment_weights = {}  # default
+
+    if type(converters) != dict:
+        converters = {}
+        
+    # time weights
+
+    # relative weight of time period
+
+    # one interval twice as long as the average is worth twice
+    # one interval half as long as the average is worth half
+
+    # time_weights = [
+    #     [time_period_duration/average_time_interval_duration
+    #       for time_period_duration in intraperiod_time_interval_duration]
+    #     for p in range(number_periods)]
+
+    time_weights = None  # nothing yet
+
+    normalised_time_interval_duration = None  # nothing yet
+
+    # create problem object
+
+    ipp = InfrastructurePlanningProblem(
+        # discount_rates=discount_rates,
+        time_frame=time_frame,
+        # reporting_periods=time_frame.reporting_periods,
+        # time_intervals=time_frame.time_interval_durations,
+        time_weights=time_weights,
+        normalised_time_interval_duration=normalised_time_interval_duration,
+        assessment_weights=assessment_weights,
+        use_prices_block=use_prices_block
+    )
+
+    # add networks and systems
+
+    for netkey, net in networks.items():
+        ipp.add_network(network_key=netkey, network=net)
+
+    # add converters
+
+    for cvtkey, cvt in converters.items():
+        ipp.add_converter(converter_key=cvtkey, converter=cvt)
+
+    # define arcs as mandatory
+
+    if type(mandatory_arcs) == list:
+        for full_arc_key in mandatory_arcs:
+            ipp.make_arc_mandatory(full_arc_key[0], full_arc_key[1:])
+
+    # if make_all_arcs_mandatory:
+
+    #     for network_key in ipp.networks:
+
+    #         for arc_key in ipp.networks[network_key].edges(keys=True):
+
+    #             # preexisting arcs are no good
+
+    #             if ipp.networks[network_key].edges[arc_key][
+    #                     Network.KEY_ARC_TECH].has_been_selected():
+
+    #                 continue
+
+    #             ipp.make_arc_mandatory(network_key, arc_key)
+
+    # set up the use of sos for arc selection
+
+    if use_sos_arcs:
+        for network_key in ipp.networks:
+            for arc_key in ipp.networks[network_key].edges(keys=True):
+                if (
+                    ipp.networks[network_key]
+                    .edges[arc_key][Network.KEY_ARC_TECH]
+                    .has_been_selected()
+                ):
+                    # skip arcs that have already been selected (pre-existing)
+                    continue
+
+                ipp.use_sos1_for_arc_selection(
+                    network_key,
+                    arc_key,
+                    use_real_variables_if_possible=(
+                        arc_use_real_variables_if_possible
+                    ),
+                    sos1_weight_method=arc_sos_weight_key,
+                )
+
+    # set up the use of sos for flow sense determination
+
+    if use_sos_sense:
+        for network_key in ipp.networks:
+            for arc_key in ipp.networks[network_key].edges(keys=True):
+                if not ipp.networks[network_key].edges[arc_key][
+                    Network.KEY_ARC_UND
+                ]:
+                    continue
+
+                ipp.use_sos1_for_flow_senses(
+                    network_key,
+                    arc_key,
+                    use_real_variables_if_possible=(
+                        sense_use_real_variables_if_possible
+                    ),
+                    use_interface_variables=sense_use_arc_interfaces,
+                    sos1_weight_method=sense_sos_weight_key,
+                )
+
+    elif sense_use_arc_interfaces:  # set up the use of arc interfaces w/o sos1
+        for network_key in ipp.networks:
+            for arc_key in ipp.networks[network_key].edges(keys=True):
+                if (
+                    ipp.networks[network_key]
+                    .edges[arc_key][Network.KEY_ARC_TECH]
+                    .has_been_selected()
+                ):
+                    continue
+
+                ipp.use_interface_variables_for_arc_selection(network_key, arc_key)
+
+    # static losses
+
+    if static_losses_mode == ipp.STATIC_LOSS_MODE_ARR:
+        ipp.place_static_losses_arrival_node()
+
+    elif static_losses_mode == ipp.STATIC_LOSS_MODE_DEP:
+        ipp.place_static_losses_departure_node()
+
+    elif static_losses_mode == ipp.STATIC_LOSS_MODE_US:
+        ipp.place_static_losses_upstream()
+
+    elif static_losses_mode == ipp.STATIC_LOSS_MODE_DS:
+        ipp.place_static_losses_downstream()
+
+    else:
+        raise ValueError("Unknown static loss modelling mode.")
+
+    # *********************************************************************
+
+    # groups
+
+    if type(arc_groups_dict) != type(None):
+        for key in arc_groups_dict:
+            ipp.create_arc_group(arc_groups_dict[key])
+
+    # *********************************************************************
+
+    # maximum number of parallel arcs
+
+    for key in max_number_parallel_arcs:
+        ipp.set_maximum_number_parallel_arcs(
+            network_key=key[0],
+            node_a=key[1],
+            node_b=key[2],
+            limit=max_number_parallel_arcs[key],
+        )
+
+    # *********************************************************************
+
+    if simplify_problem:
+        ipp.simplify_peak_total_assessments()
+
+    # *********************************************************************
+    
+    # instantiate (disable the default case v-a-v fixed losses)
+
+    # ipp.instantiate(place_fixed_losses_upstream_if_possible=False)
+
+    ipp.instantiate(initialise_ancillary_sets=init_aux_sets)
+    # ipp.instance.pprint()
+    # optimise
+    ipp.optimise(
+        solver_name=solver,
+        solver_options=solver_options,
+        output_options={},
+        print_solver_output=print_solver_output,
+    )
+    # ipp.instance.pprint()
+    # return the problem object
+    return ipp
+
+# *****************************************************************************
+# *****************************************************************************
\ No newline at end of file
diff --git a/tests/test_esipp_prices.py b/tests/test_esipp_prices.py
index a7c6d59d9f707a88b8d6f9b66b150c4d2b187d37..9745b6855f5ea7d7873e42c448e7c351932eb513 100644
--- a/tests/test_esipp_prices.py
+++ b/tests/test_esipp_prices.py
@@ -19,230 +19,12 @@ from src.topupopt.problems.esipp.resource import ResourcePrice
 from src.topupopt.problems.esipp.utils import statistics
 from src.topupopt.problems.esipp.time import EconomicTimeFrame
 # from src.topupopt.problems.esipp.converter import Converter
+from test_esipp import build_solve_ipp
 
 # *****************************************************************************
 # *****************************************************************************
 
 class TestESIPPProblem:
-    
-    solver = 'glpk'
-    # solver = 'scip'
-    # solver = 'cbc'
-    
-    def build_solve_ipp(
-        self,
-        solver: str = None,
-        solver_options: dict = None,
-        use_sos_arcs: bool = False,
-        arc_sos_weight_key: str = (InfrastructurePlanningProblem.SOS1_ARC_WEIGHTS_NONE),
-        arc_use_real_variables_if_possible: bool = False,
-        use_sos_sense: bool = False,
-        sense_sos_weight_key: int = (
-            InfrastructurePlanningProblem.SOS1_SENSE_WEIGHT_NOMINAL_HIGHER
-        ),
-        sense_use_real_variables_if_possible: bool = False,
-        sense_use_arc_interfaces: bool = False,
-        perform_analysis: bool = False,
-        plot_results: bool = False,
-        print_solver_output: bool = False,
-        time_frame: EconomicTimeFrame = None,
-        networks: dict = None,
-        converters: dict = None,
-        static_losses_mode=None,
-        mandatory_arcs: list = None,
-        max_number_parallel_arcs: dict = None,
-        arc_groups_dict: dict = None,
-        init_aux_sets: bool = False,
-        # discount_rates: dict = None,
-        assessment_weights: dict = None,
-        simplify_problem: bool = False,
-        use_prices_block: bool = False
-    ):
-        if type(solver) == type(None):
-            solver = self.solver
-        
-        if type(assessment_weights) != dict:
-            assessment_weights = {}  # default
-
-        if type(converters) != dict:
-            converters = {}
-            
-        # time weights
-
-        # relative weight of time period
-
-        # one interval twice as long as the average is worth twice
-        # one interval half as long as the average is worth half
-
-        # time_weights = [
-        #     [time_period_duration/average_time_interval_duration
-        #       for time_period_duration in intraperiod_time_interval_duration]
-        #     for p in range(number_periods)]
-
-        time_weights = None  # nothing yet
-
-        normalised_time_interval_duration = None  # nothing yet
-
-        # create problem object
-
-        ipp = InfrastructurePlanningProblem(
-            # discount_rates=discount_rates,
-            time_frame=time_frame,
-            # reporting_periods=time_frame.reporting_periods,
-            # time_intervals=time_frame.time_interval_durations,
-            time_weights=time_weights,
-            normalised_time_interval_duration=normalised_time_interval_duration,
-            assessment_weights=assessment_weights,
-            use_prices_block=use_prices_block
-        )
-
-        # add networks and systems
-
-        for netkey, net in networks.items():
-            ipp.add_network(network_key=netkey, network=net)
-
-        # add converters
-
-        for cvtkey, cvt in converters.items():
-            ipp.add_converter(converter_key=cvtkey, converter=cvt)
-
-        # define arcs as mandatory
-
-        if type(mandatory_arcs) == list:
-            for full_arc_key in mandatory_arcs:
-                ipp.make_arc_mandatory(full_arc_key[0], full_arc_key[1:])
-
-        # if make_all_arcs_mandatory:
-
-        #     for network_key in ipp.networks:
-
-        #         for arc_key in ipp.networks[network_key].edges(keys=True):
-
-        #             # preexisting arcs are no good
-
-        #             if ipp.networks[network_key].edges[arc_key][
-        #                     Network.KEY_ARC_TECH].has_been_selected():
-
-        #                 continue
-
-        #             ipp.make_arc_mandatory(network_key, arc_key)
-
-        # set up the use of sos for arc selection
-
-        if use_sos_arcs:
-            for network_key in ipp.networks:
-                for arc_key in ipp.networks[network_key].edges(keys=True):
-                    if (
-                        ipp.networks[network_key]
-                        .edges[arc_key][Network.KEY_ARC_TECH]
-                        .has_been_selected()
-                    ):
-                        continue
-
-                    ipp.use_sos1_for_arc_selection(
-                        network_key,
-                        arc_key,
-                        use_real_variables_if_possible=(
-                            arc_use_real_variables_if_possible
-                        ),
-                        sos1_weight_method=arc_sos_weight_key,
-                    )
-
-        # set up the use of sos for flow sense determination
-
-        if use_sos_sense:
-            for network_key in ipp.networks:
-                for arc_key in ipp.networks[network_key].edges(keys=True):
-                    if not ipp.networks[network_key].edges[arc_key][
-                        Network.KEY_ARC_UND
-                    ]:
-                        continue
-
-                    ipp.use_sos1_for_flow_senses(
-                        network_key,
-                        arc_key,
-                        use_real_variables_if_possible=(
-                            sense_use_real_variables_if_possible
-                        ),
-                        use_interface_variables=sense_use_arc_interfaces,
-                        sos1_weight_method=sense_sos_weight_key,
-                    )
-
-        elif sense_use_arc_interfaces:  # set up the use of arc interfaces w/o sos1
-            for network_key in ipp.networks:
-                for arc_key in ipp.networks[network_key].edges(keys=True):
-                    if (
-                        ipp.networks[network_key]
-                        .edges[arc_key][Network.KEY_ARC_TECH]
-                        .has_been_selected()
-                    ):
-                        continue
-
-                    ipp.use_interface_variables_for_arc_selection(network_key, arc_key)
-
-        # static losses
-
-        if static_losses_mode == ipp.STATIC_LOSS_MODE_ARR:
-            ipp.place_static_losses_arrival_node()
-
-        elif static_losses_mode == ipp.STATIC_LOSS_MODE_DEP:
-            ipp.place_static_losses_departure_node()
-
-        elif static_losses_mode == ipp.STATIC_LOSS_MODE_US:
-            ipp.place_static_losses_upstream()
-
-        elif static_losses_mode == ipp.STATIC_LOSS_MODE_DS:
-            ipp.place_static_losses_downstream()
-
-        else:
-            raise ValueError("Unknown static loss modelling mode.")
-
-        # *********************************************************************
-
-        # groups
-
-        if type(arc_groups_dict) != type(None):
-            for key in arc_groups_dict:
-                ipp.create_arc_group(arc_groups_dict[key])
-
-        # *********************************************************************
-
-        # maximum number of parallel arcs
-
-        for key in max_number_parallel_arcs:
-            ipp.set_maximum_number_parallel_arcs(
-                network_key=key[0],
-                node_a=key[1],
-                node_b=key[2],
-                limit=max_number_parallel_arcs[key],
-            )
-
-        # *********************************************************************
-
-        if simplify_problem:
-            ipp.simplify_peak_total_assessments()
-
-        # *********************************************************************
-        
-        # instantiate (disable the default case v-a-v fixed losses)
-
-        # ipp.instantiate(place_fixed_losses_upstream_if_possible=False)
-
-        ipp.instantiate(initialise_ancillary_sets=init_aux_sets)
-        # ipp.instance.pprint()
-        # optimise
-        ipp.optimise(
-            solver_name=solver,
-            solver_options=solver_options,
-            output_options={},
-            print_solver_output=print_solver_output,
-        )
-        # ipp.instance.pprint()
-        # return the problem object
-        return ipp
-
-        # *********************************************************************
-        # *********************************************************************
 
     # *************************************************************************
     # *************************************************************************
@@ -293,7 +75,7 @@ class TestESIPPProblem:
         mynet.add_directed_arc(node_key_a=node_IMP, node_key_b=node_A, arcs=arc_tech_IA)
 
         # no sos, regular time intervals
-        ipp = self.build_solve_ipp(
+        ipp = build_solve_ipp(
             solver_options={},
             perform_analysis=False,
             plot_results=False,  # True,
@@ -397,7 +179,7 @@ class TestESIPPProblem:
         mynet.add_directed_arc(node_key_a=node_IMP, node_key_b=node_A, arcs=arc_tech_IA)
 
         # no sos, regular time intervals
-        ipp = self.build_solve_ipp(
+        ipp = build_solve_ipp(
             solver_options={},
             perform_analysis=False,
             plot_results=False,  # True,
@@ -412,10 +194,13 @@ class TestESIPPProblem:
         )
 
         assert not ipp.has_peak_total_assessments()
+        # print(ipp.results["Problem"][0]["Number of constraints"])
+        # print(ipp.results["Problem"][0]["Number of variables"])
+        # print(ipp.results["Problem"][0]["Number of nonzeros"])
         assert ipp.results["Problem"][0]["Number of constraints"] == 14 # 10 prior to nonconvex block
         assert ipp.results["Problem"][0]["Number of variables"] == 13 # 11 prior to nonconvex block
         assert ipp.results["Problem"][0]["Number of nonzeros"] == 28 # 20 prior to nonconvex block
-
+        
         # *********************************************************************
         # *********************************************************************
 
@@ -504,7 +289,7 @@ class TestESIPPProblem:
         error_raised = False
         try:
             # no sos, regular time intervals
-            self.build_solve_ipp(
+            build_solve_ipp(
                 solver_options={},
                 perform_analysis=False,
                 plot_results=False,  # True,
@@ -573,7 +358,7 @@ class TestESIPPProblem:
         mynet.add_directed_arc(node_key_a=node_A, node_key_b=node_EXP, arcs=arc_tech_IA)
 
         # no sos, regular time intervals
-        ipp = self.build_solve_ipp(
+        ipp = build_solve_ipp(
             solver_options={},
             perform_analysis=False,
             plot_results=False,  # True,
@@ -680,7 +465,7 @@ class TestESIPPProblem:
         mynet.add_directed_arc(node_key_a=node_A, node_key_b=node_EXP, arcs=arc_tech_IA)
 
         # no sos, regular time intervals
-        ipp = self.build_solve_ipp(
+        ipp = build_solve_ipp(
             solver_options={},
             perform_analysis=False,
             plot_results=False,  # True,
@@ -790,7 +575,7 @@ class TestESIPPProblem:
         error_raised = False
         try:
             # no sos, regular time intervals
-            self.build_solve_ipp(
+            build_solve_ipp(
                 solver_options={},
                 perform_analysis=False,
                 plot_results=False,  # True,
@@ -887,7 +672,7 @@ class TestESIPPProblem:
         mynet.add_directed_arc(node_key_a=node_A, node_key_b=node_EXP, arcs=arc_tech_AE)
 
         # no sos, regular time intervals
-        ipp = self.build_solve_ipp(
+        ipp = build_solve_ipp(
             solver_options={},
             perform_analysis=False,
             plot_results=False,  # True,
@@ -1038,7 +823,7 @@ class TestESIPPProblem:
         )
     
         # no sos, regular time intervals
-        ipp = self.build_solve_ipp(
+        ipp = build_solve_ipp(
             solver_options={},
             perform_analysis=False,
             plot_results=False,  # True,
diff --git a/tests/test_esipp_problem.py b/tests/test_esipp_problem.py
index 511b874aa72c49202f2e425d9e52c927bfe55374..3289150f82a3413f4fda276985de9dacb73d3b6c 100644
--- a/tests/test_esipp_problem.py
+++ b/tests/test_esipp_problem.py
@@ -4,8 +4,7 @@
 import math
 
 # local
-# import numpy as np
-# import networkx as nx
+import pytest
 import pyomo.environ as pyo
 
 # import src.topupopt.problems.esipp.utils as utils
@@ -18,234 +17,26 @@ from src.topupopt.problems.esipp.resource import ResourcePrice
 from src.topupopt.problems.esipp.utils import statistics
 from src.topupopt.problems.esipp.time import EconomicTimeFrame
 # from src.topupopt.problems.esipp.converter import Converter
+from test_esipp import build_solve_ipp
 
 # *****************************************************************************
 # *****************************************************************************
 
 class TestESIPPProblem:
-    
-    solver = 'glpk'
-    # solver = 'scip'
-    # solver = 'cbc'
-    
-    def build_solve_ipp(
-        self,
-        solver: str = None,
-        solver_options: dict = None,
-        use_sos_arcs: bool = False,
-        arc_sos_weight_key: str = (InfrastructurePlanningProblem.SOS1_ARC_WEIGHTS_NONE),
-        arc_use_real_variables_if_possible: bool = False,
-        use_sos_sense: bool = False,
-        sense_sos_weight_key: int = (
-            InfrastructurePlanningProblem.SOS1_SENSE_WEIGHT_NOMINAL_HIGHER
-        ),
-        sense_use_real_variables_if_possible: bool = False,
-        sense_use_arc_interfaces: bool = False,
-        perform_analysis: bool = False,
-        plot_results: bool = False,
-        print_solver_output: bool = False,
-        time_frame: EconomicTimeFrame = None,
-        networks: dict = None,
-        converters: dict = None,
-        static_losses_mode=None,
-        mandatory_arcs: list = None,
-        max_number_parallel_arcs: dict = None,
-        arc_groups_dict: dict = None,
-        init_aux_sets: bool = False,
-        # discount_rates: dict = None,
-        assessment_weights: dict = None,
-        simplify_problem: bool = False,
-    ):
-        if type(solver) == type(None):
-            solver = self.solver
-        
-        if type(assessment_weights) != dict:
-            assessment_weights = {}  # default
-
-        if type(converters) != dict:
-            converters = {}
-            
-        # time weights
-
-        # relative weight of time period
-
-        # one interval twice as long as the average is worth twice
-        # one interval half as long as the average is worth half
-
-        # time_weights = [
-        #     [time_period_duration/average_time_interval_duration
-        #       for time_period_duration in intraperiod_time_interval_duration]
-        #     for p in range(number_periods)]
-
-        time_weights = None  # nothing yet
-
-        normalised_time_interval_duration = None  # nothing yet
-
-        # create problem object
-
-        ipp = InfrastructurePlanningProblem(
-            # discount_rates=discount_rates,
-            time_frame=time_frame,
-            # reporting_periods=time_frame.reporting_periods,
-            # time_intervals=time_frame.time_interval_durations,
-            time_weights=time_weights,
-            normalised_time_interval_duration=normalised_time_interval_duration,
-            assessment_weights=assessment_weights,
-        )
-
-        # add networks and systems
-
-        for netkey, net in networks.items():
-            ipp.add_network(network_key=netkey, network=net)
-
-        # add converters
-
-        for cvtkey, cvt in converters.items():
-            ipp.add_converter(converter_key=cvtkey, converter=cvt)
-
-        # define arcs as mandatory
-
-        if type(mandatory_arcs) == list:
-            for full_arc_key in mandatory_arcs:
-                ipp.make_arc_mandatory(full_arc_key[0], full_arc_key[1:])
-
-        # if make_all_arcs_mandatory:
-
-        #     for network_key in ipp.networks:
-
-        #         for arc_key in ipp.networks[network_key].edges(keys=True):
-
-        #             # preexisting arcs are no good
-
-        #             if ipp.networks[network_key].edges[arc_key][
-        #                     Network.KEY_ARC_TECH].has_been_selected():
-
-        #                 continue
-
-        #             ipp.make_arc_mandatory(network_key, arc_key)
-
-        # set up the use of sos for arc selection
-
-        if use_sos_arcs:
-            for network_key in ipp.networks:
-                for arc_key in ipp.networks[network_key].edges(keys=True):
-                    if (
-                        ipp.networks[network_key]
-                        .edges[arc_key][Network.KEY_ARC_TECH]
-                        .has_been_selected()
-                    ):
-                        continue
-
-                    ipp.use_sos1_for_arc_selection(
-                        network_key,
-                        arc_key,
-                        use_real_variables_if_possible=(
-                            arc_use_real_variables_if_possible
-                        ),
-                        sos1_weight_method=arc_sos_weight_key,
-                    )
-
-        # set up the use of sos for flow sense determination
-
-        if use_sos_sense:
-            for network_key in ipp.networks:
-                for arc_key in ipp.networks[network_key].edges(keys=True):
-                    if not ipp.networks[network_key].edges[arc_key][
-                        Network.KEY_ARC_UND
-                    ]:
-                        continue
-
-                    ipp.use_sos1_for_flow_senses(
-                        network_key,
-                        arc_key,
-                        use_real_variables_if_possible=(
-                            sense_use_real_variables_if_possible
-                        ),
-                        use_interface_variables=sense_use_arc_interfaces,
-                        sos1_weight_method=sense_sos_weight_key,
-                    )
-
-        elif sense_use_arc_interfaces:  # set up the use of arc interfaces w/o sos1
-            for network_key in ipp.networks:
-                for arc_key in ipp.networks[network_key].edges(keys=True):
-                    if (
-                        ipp.networks[network_key]
-                        .edges[arc_key][Network.KEY_ARC_TECH]
-                        .has_been_selected()
-                    ):
-                        continue
-
-                    ipp.use_interface_variables_for_arc_selection(network_key, arc_key)
-
-        # static losses
-
-        if static_losses_mode == ipp.STATIC_LOSS_MODE_ARR:
-            ipp.place_static_losses_arrival_node()
-
-        elif static_losses_mode == ipp.STATIC_LOSS_MODE_DEP:
-            ipp.place_static_losses_departure_node()
-
-        elif static_losses_mode == ipp.STATIC_LOSS_MODE_US:
-            ipp.place_static_losses_upstream()
-
-        elif static_losses_mode == ipp.STATIC_LOSS_MODE_DS:
-            ipp.place_static_losses_downstream()
-
-        else:
-            raise ValueError("Unknown static loss modelling mode.")
-
-        # *********************************************************************
-
-        # groups
-
-        if type(arc_groups_dict) != type(None):
-            for key in arc_groups_dict:
-                ipp.create_arc_group(arc_groups_dict[key])
-
-        # *********************************************************************
-
-        # maximum number of parallel arcs
-
-        for key in max_number_parallel_arcs:
-            ipp.set_maximum_number_parallel_arcs(
-                network_key=key[0],
-                node_a=key[1],
-                node_b=key[2],
-                limit=max_number_parallel_arcs[key],
-            )
-
-        # *********************************************************************
-
-        if simplify_problem:
-            ipp.simplify_peak_total_assessments()
-
-        # *********************************************************************
-        
-        # instantiate (disable the default case v-a-v fixed losses)
-
-        # ipp.instantiate(place_fixed_losses_upstream_if_possible=False)
-
-        ipp.instantiate(initialise_ancillary_sets=init_aux_sets)
-        
-        # optimise
-        ipp.optimise(
-            solver_name=solver,
-            solver_options=solver_options,
-            output_options={},
-            print_solver_output=print_solver_output,
-        )
-
-        # return the problem object
-
-        return ipp
-
-        # *********************************************************************
-        # *********************************************************************
 
     # *************************************************************************
     # *************************************************************************
-
-    def test_single_network_single_arc_problem(self):
+    
+    @pytest.mark.parametrize(
+        "use_sos_arcs, arc_sos_weight_key", 
+        [(True, InfrastructurePlanningProblem.SOS1_ARC_WEIGHTS_NONE),
+         (True, InfrastructurePlanningProblem.SOS1_ARC_WEIGHTS_CAP),
+         (True, InfrastructurePlanningProblem.SOS1_ARC_WEIGHTS_COST),
+         (True, InfrastructurePlanningProblem.SOS1_ARC_WEIGHTS_SPEC_CAP),
+         (True, InfrastructurePlanningProblem.SOS1_ARC_WEIGHTS_SPEC_COST),
+         (False, None)]
+        )
+    def test_single_network_single_arc_problem(self, use_sos_arcs, arc_sos_weight_key):
         
         # assessment
         q = 0
@@ -292,8 +83,10 @@ class TestESIPPProblem:
         mynet.add_directed_arc(node_key_a=node_IMP, node_key_b=node_A, arcs=arc_tech_IA)
 
         # no sos, regular time intervals
-        ipp = self.build_solve_ipp(
+        ipp = build_solve_ipp(
             solver_options={},
+            use_sos_arcs=use_sos_arcs,
+            arc_sos_weight_key=arc_sos_weight_key,
             perform_analysis=False,
             plot_results=False,  # True,
             print_solver_output=False,
@@ -358,7 +151,7 @@ class TestESIPPProblem:
         
     # *************************************************************************
     # *************************************************************************
-
+    
     def test_single_network_two_arcs_problem(self):
         
         # TODO: test simplifying this problem
@@ -433,8 +226,10 @@ class TestESIPPProblem:
         mynet.add_directed_arc(node_key_a=node_A, node_key_b=node_EXP, arcs=arc_tech_AE)
         
         # no sos, regular time intervals
-        ipp = self.build_solve_ipp(
+        ipp = build_solve_ipp(
             solver_options={},
+            # use_sos_arcs=use_sos_arcs,
+            # arc_sos_weight_key=arc_sos_weight_key,
             perform_analysis=False,
             plot_results=False,  # True,
             print_solver_output=False,
@@ -501,7 +296,16 @@ class TestESIPPProblem:
     # *************************************************************************
     # *************************************************************************
 
-    def test_single_network_single_arc_problem_simpler(self):
+    @pytest.mark.parametrize(
+        "use_sos_arcs, arc_sos_weight_key", 
+        [(True, InfrastructurePlanningProblem.SOS1_ARC_WEIGHTS_NONE),
+         (True, InfrastructurePlanningProblem.SOS1_ARC_WEIGHTS_CAP),
+         (True, InfrastructurePlanningProblem.SOS1_ARC_WEIGHTS_COST),
+         (True, InfrastructurePlanningProblem.SOS1_ARC_WEIGHTS_SPEC_CAP),
+         (True, InfrastructurePlanningProblem.SOS1_ARC_WEIGHTS_SPEC_COST),
+         (False, None)]
+        )
+    def test_single_network_single_arc_problem_simpler(self, use_sos_arcs, arc_sos_weight_key):
         
         # assessment
         q = 0
@@ -549,7 +353,7 @@ class TestESIPPProblem:
         mynet.add_directed_arc(node_key_a=node_IMP, node_key_b=node_A, arcs=arc_tech_IA)
 
         # no sos, regular time intervals
-        ipp = self.build_solve_ipp(
+        ipp = build_solve_ipp(
             solver_options={},
             perform_analysis=False,
             plot_results=False,  # True,
@@ -653,7 +457,7 @@ class TestESIPPProblem:
 
         # no sos, regular time intervals
 
-        ipp = self.build_solve_ipp(
+        ipp = build_solve_ipp(
             solver_options={},
             perform_analysis=False,
             plot_results=False,  # True,
@@ -773,7 +577,7 @@ class TestESIPPProblem:
         mynet.add_directed_arc(node_key_a=node_IMP, node_key_b=node_A, arcs=arc_tech_IA)
 
         # no sos, regular time intervals
-        ipp = self.build_solve_ipp(
+        ipp = build_solve_ipp(
             solver_options={},
             perform_analysis=False,
             plot_results=False,  # True,
@@ -856,7 +660,7 @@ class TestESIPPProblem:
         mynet.add_directed_arc(node_key_a=node_IMP, node_key_b=node_A, arcs=arc_tech_IA)
 
         # no sos, regular time intervals
-        ipp = self.build_solve_ipp(
+        ipp = build_solve_ipp(
             solver_options={},
             perform_analysis=False,
             plot_results=False,  # True,
@@ -979,7 +783,7 @@ class TestESIPPProblem:
         mynet.add_directed_arc(node_key_a=node_IMP, node_key_b=node_A, arcs=arc_tech_IA)
 
         # no sos, regular time intervals
-        ipp = self.build_solve_ipp(
+        ipp = build_solve_ipp(
             solver_options={},
             perform_analysis=False,
             plot_results=False,  # True,
@@ -1069,7 +873,7 @@ class TestESIPPProblem:
         )
     
         # no sos, regular time intervals
-        ipp = self.build_solve_ipp(
+        ipp = build_solve_ipp(
             solver_options={},
             perform_analysis=False,
             plot_results=False,  # True,
@@ -1159,7 +963,7 @@ class TestESIPPProblem:
         )
     
         # no sos, regular time intervals
-        ipp = self.build_solve_ipp(
+        ipp = build_solve_ipp(
             solver_options={},
             perform_analysis=False,
             plot_results=False,
@@ -1260,7 +1064,7 @@ class TestESIPPProblem:
         )
     
         # no sos, regular time intervals
-        ipp = self.build_solve_ipp(
+        ipp = build_solve_ipp(
             solver_options={},
             perform_analysis=False,
             plot_results=False,  # True,
@@ -1327,7 +1131,7 @@ class TestESIPPProblem:
         )
     
         # no sos, regular time intervals
-        ipp = self.build_solve_ipp(
+        ipp = build_solve_ipp(
             solver_options={},
             perform_analysis=False,
             plot_results=False,  # True,
@@ -1452,7 +1256,7 @@ class TestESIPPProblem:
         )
     
         # no sos, regular time intervals
-        ipp = self.build_solve_ipp(
+        ipp = build_solve_ipp(
             solver_options={},
             perform_analysis=False,
             plot_results=False,  # True,
@@ -1619,7 +1423,7 @@ class TestESIPPProblem:
         )
     
         # no sos, regular time intervals
-        ipp = self.build_solve_ipp(
+        ipp = build_solve_ipp(
             solver_options={},
             perform_analysis=False,
             plot_results=False,  # True,
@@ -1781,7 +1585,7 @@ class TestESIPPProblem:
         )
     
         # no sos, regular time intervals
-        ipp = self.build_solve_ipp(
+        ipp = build_solve_ipp(
             solver_options={},
             perform_analysis=False,
             plot_results=False,  # True,
@@ -1919,7 +1723,7 @@ class TestESIPPProblem:
         )
     
         # no sos, regular time intervals
-        ipp = self.build_solve_ipp(
+        ipp = build_solve_ipp(
             solver_options={},solver='scip',
             perform_analysis=False,
             plot_results=False,  # True,
@@ -2146,7 +1950,7 @@ class TestESIPPProblem:
         solver_options["relative_mip_gap"] = 0
         solver_options["absolute_mip_gap"] = 1e-4
     
-        ipp = self.build_solve_ipp(
+        ipp = build_solve_ipp(
             solver_options=solver_options,
             use_sos_arcs=False,
             arc_sos_weight_key=None,
@@ -2480,7 +2284,7 @@ class TestESIPPProblem:
         solver_options["relative_mip_gap"] = 0
         solver_options["absolute_mip_gap"] = 1e-4
     
-        ipp = self.build_solve_ipp(
+        ipp = build_solve_ipp(
             solver_options=solver_options,
             use_sos_arcs=False,
             arc_sos_weight_key=None,
@@ -2765,7 +2569,7 @@ class TestESIPPProblem:
                             Network.KEY_ARC_TECH].options_selected.index(True)
                         ] = False
                         
-            ipp = self.build_solve_ipp(
+            ipp = build_solve_ipp(
                 solver_options=solver_options,
                 use_sos_arcs=False,
                 arc_sos_weight_key=None,
@@ -3073,7 +2877,7 @@ class TestESIPPProblem:
                             Network.KEY_ARC_TECH].options_selected.index(True)
                         ] = False
             
-            ipp = self.build_solve_ipp(
+            ipp = build_solve_ipp(
                 solver_options=solver_options,
                 perform_analysis=False,
                 plot_results=False,  # True,
@@ -3241,7 +3045,7 @@ class TestESIPPProblem:
         )
     
         # no sos, regular time intervals
-        ipp = self.build_solve_ipp(
+        ipp = build_solve_ipp(
             solver_options={},
             perform_analysis=False,
             plot_results=False,  # True,
@@ -3425,7 +3229,7 @@ class TestESIPPProblem:
                             Network.KEY_ARC_TECH].options_selected.index(True)
                         ] = False
             
-            ipp = self.build_solve_ipp(
+            ipp = build_solve_ipp(
                 solver_options={},
                 use_sos_arcs=False,
                 arc_sos_weight_key=None,
@@ -3812,7 +3616,7 @@ class TestESIPPProblem:
                             Network.KEY_ARC_TECH].options_selected.index(True)
                         ] = False
             
-            ipp = self.build_solve_ipp(
+            ipp = build_solve_ipp(
                 solver_options={},
                 use_sos_arcs=False,
                 arc_sos_weight_key=None,
@@ -4203,7 +4007,7 @@ class TestESIPPProblem:
     
         for static_losses_mode in InfrastructurePlanningProblem.STATIC_LOSS_MODES:
     
-            ipp = self.build_solve_ipp(
+            ipp = build_solve_ipp(
                 solver_options={},
                 perform_analysis=False,
                 plot_results=False,  # True,
@@ -4825,7 +4629,7 @@ class TestESIPPProblem:
     
         for static_losses_mode in InfrastructurePlanningProblem.STATIC_LOSS_MODES:
     
-            ipp = self.build_solve_ipp(
+            ipp = build_solve_ipp(
                 solver_options={},
                 perform_analysis=False,
                 plot_results=False,  # True,
@@ -5394,7 +5198,7 @@ class TestESIPPProblem:
                             Network.KEY_ARC_TECH].options_selected.index(True)
                         ] = False
             
-            ipp = self.build_solve_ipp(
+            ipp = build_solve_ipp(
                 solver_options={},
                 perform_analysis=False,
                 plot_results=False,  
@@ -5541,7 +5345,7 @@ class TestESIPPProblem:
                 InfrastructurePlanningProblem.STATIC_LOSS_MODE_DEP
                 ]:
             # TODO: make this work with GLPK and SCIP
-            ipp = self.build_solve_ipp(
+            ipp = build_solve_ipp(
                 solver='cbc', # does not work with GLPK nor SCIP
                 solver_options={},
                 perform_analysis=False,
@@ -5690,7 +5494,7 @@ class TestESIPPProblem:
                             Network.KEY_ARC_TECH].options_selected.index(True)
                         ] = False
             
-            ipp = self.build_solve_ipp(
+            ipp = build_solve_ipp(
                 solver_options={},
                 perform_analysis=False,
                 plot_results=False,  # True,
@@ -5964,7 +5768,7 @@ class TestESIPPProblem:
                             Network.KEY_ARC_TECH].options_selected.index(True)
                         ] = False
             
-            ipp = self.build_solve_ipp(
+            ipp = build_solve_ipp(
                 solver_options={},
                 perform_analysis=False,
                 plot_results=False,  # True,
@@ -6244,7 +6048,7 @@ class TestESIPPProblem:
                             Network.KEY_ARC_TECH].options_selected.index(True)
                         ] = False
             
-            ipp = self.build_solve_ipp(
+            ipp = build_solve_ipp(
                 solver_options={},
                 perform_analysis=False,
                 plot_results=False,  # True,
@@ -6519,7 +6323,7 @@ class TestESIPPProblem:
             #                 Network.KEY_ARC_TECH].options_selected.index(True)
             #             ] = False
             
-            ipp = self.build_solve_ipp(
+            ipp = build_solve_ipp(
                 solver_options={},
                 perform_analysis=False,
                 plot_results=False,  # True,
@@ -6824,7 +6628,7 @@ class TestESIPPProblem:
     
         # no sos, regular time intervals
     
-        ipp = self.build_solve_ipp(
+        ipp = build_solve_ipp(
             solver_options={},
             plot_results=False,  # True,
             print_solver_output=False,
@@ -6989,7 +6793,7 @@ class TestESIPPProblem:
     
         # no sos, regular time intervals
     
-        ipp = self.build_solve_ipp(
+        ipp = build_solve_ipp(
             solver='cbc', # TODO: make this work with other solvers
             solver_options={},
             plot_results=False,  # True,
@@ -7129,7 +6933,7 @@ class TestESIPPProblem:
         mynet.add_directed_arc(node_key_a=imp_node_key, node_key_b=node_A, arcs=arcs_ia2)
     
         # no sos, regular time intervals    
-        ipp = self.build_solve_ipp(
+        ipp = build_solve_ipp(
             solver='cbc', # TODO: make this work with other solvers
             solver_options={},
             plot_results=False,  # True,
@@ -7256,7 +7060,7 @@ class TestESIPPProblem:
         )
     
         # no sos, regular time intervals    
-        ipp = self.build_solve_ipp(
+        ipp = build_solve_ipp(
             solver='cbc', # TODO: make this work with other solvers
             solver_options={},
             plot_results=False,  # True,
@@ -7417,7 +7221,7 @@ class TestESIPPProblem:
 
     #     # no sos, regular time intervals
 
-    #     ipp = self.build_solve_ipp(
+    #     ipp = build_solve_ipp(
     #         solver_options={},
     #         perform_analysis=False,
     #         plot_results=False,  # True,
@@ -7581,7 +7385,7 @@ class TestESIPPProblem:
             mynet.add_directed_arc(*node_pair, arcs=new_arc_tech)
 
         # no sos, regular time intervals
-        ipp = self.build_solve_ipp(
+        ipp = build_solve_ipp(
             solver_options={},
             perform_analysis=False,
             plot_results=False,  # True,
@@ -7724,7 +7528,7 @@ class TestESIPPProblem:
             mynet.add_directed_arc(*node_pair, arcs=new_arc_tech)
 
         # no sos, regular time intervals
-        ipp = self.build_solve_ipp(
+        ipp = build_solve_ipp(
             solver_options={},
             perform_analysis=False,
             plot_results=False,  # True,
diff --git a/tests/test_solvers.py b/tests/test_solvers.py
index 7f0a728322c65e460f30796ddecb72760290b8a4..44a28c895df299ea944f2c03b8563fc8a67c9f73 100644
--- a/tests/test_solvers.py
+++ b/tests/test_solvers.py
@@ -12,6 +12,7 @@ import random
 # *****************************************************************************
 # *****************************************************************************
 
+# TODO: use pytest to parameterise the tests to use different solvers
 
 class TestSolvers:
     # *************************************************************************