Skip to content

Commit e3a7829

Browse files
Add conftest for water
1 parent 94e1794 commit e3a7829

File tree

1 file changed

+115
-0
lines changed

1 file changed

+115
-0
lines changed
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
"""Common fixtures for water module tests.
2+
3+
This conftest provides shared fixtures to reduce test boilerplate and ensure
4+
consistent scenario and context setup across water module tests.
5+
"""
6+
7+
import pandas as pd
8+
import pytest
9+
from message_ix import Scenario
10+
11+
from message_ix_models import ScenarioInfo
12+
from message_ix_models.model.structure import get_codes
13+
from message_ix_models.util import package_data_path
14+
15+
16+
@pytest.fixture(scope="function")
17+
def water_scenario(request, test_context):
18+
"""Create a water module test scenario with standardized setup.
19+
20+
This fixture handles common setup for water module tests:
21+
- Creates a basic scenario with standard sets
22+
- Configures context with water-specific parameters
23+
- Computes nodes from region codelists
24+
- Sets up basin mappings when needed
25+
26+
Parameters are passed via indirect parametrization:
27+
28+
@pytest.mark.parametrize(
29+
"water_scenario",
30+
[
31+
{"regions": "R12", "type_reg": "global", "RCP": "6p0"},
32+
{"regions": "ZMB", "type_reg": "country", "SDG": "baseline"},
33+
],
34+
indirect=True,
35+
)
36+
def test_something(water_scenario):
37+
scenario = water_scenario["scenario"]
38+
context = water_scenario["context"]
39+
40+
Supported parameters:
41+
- regions: str, default "R12" (e.g., "R11", "R12", "ZMB", "R14")
42+
- type_reg: str, default "global" (options: "global", "country")
43+
- time: str, default "year" (options: "year", "month")
44+
- RCP: str, optional (e.g., "2p6", "6p0", "7p0", "no_climate")
45+
- REL: str, optional (e.g., "low", "med", "high")
46+
- SDG: str/bool, optional (e.g., "baseline", "not_baseline", "ambitious", True)
47+
- nexus_set: str, optional (e.g., "nexus", "cooling")
48+
- setup_basins: bool, default False - whether to setup valid_basins
49+
50+
Returns
51+
-------
52+
dict
53+
Dictionary with keys:
54+
- "scenario": message_ix.Scenario
55+
- "context": message_ix_models.Context
56+
"""
57+
# Extract parameters from request.param or use defaults
58+
if hasattr(request, "param"):
59+
params = request.param if isinstance(request.param, dict) else {}
60+
else:
61+
params = {}
62+
63+
regions = params.get("regions", "R12")
64+
type_reg = params.get("type_reg", "global")
65+
time = params.get("time", "year")
66+
RCP = params.get("RCP")
67+
REL = params.get("REL")
68+
SDG = params.get("SDG")
69+
nexus_set = params.get("nexus_set")
70+
setup_basins = params.get("setup_basins", False)
71+
72+
# Setup context
73+
test_context.type_reg = type_reg
74+
test_context.regions = regions
75+
test_context.time = time
76+
77+
if RCP is not None:
78+
test_context.RCP = RCP
79+
if REL is not None:
80+
test_context.REL = REL
81+
if SDG is not None:
82+
test_context.SDG = SDG
83+
if nexus_set is not None:
84+
test_context.nexus_set = nexus_set
85+
86+
# Compute nodes from codes
87+
nodes = get_codes(f"node/{regions}")
88+
nodes = list(map(str, nodes[nodes.index("World")].child))
89+
test_context.map_ISO_c = {regions: nodes[0]}
90+
91+
# Setup valid basins if requested
92+
if setup_basins:
93+
basin_file = f"basins_by_region_simpl_{regions}.csv"
94+
basin_path = package_data_path("water", "delineation", basin_file)
95+
df_basins = pd.read_csv(basin_path)
96+
test_context.valid_basins = set(df_basins["BCU_name"].astype(str))
97+
98+
# Create scenario
99+
mp = test_context.get_platform()
100+
scenario_info = {
101+
"mp": mp,
102+
"model": f"{request.node.name}/test water model",
103+
"scenario": f"{request.node.name}/test water scenario",
104+
"version": "new",
105+
}
106+
s = Scenario(**scenario_info)
107+
s.add_horizon(year=[2020, 2030, 2040])
108+
s.add_set("technology", ["tech1", "tech2"])
109+
s.add_set("year", [2020, 2030, 2040])
110+
s.commit(comment="basic water test model")
111+
112+
test_context.set_scenario(s)
113+
test_context["water build info"] = ScenarioInfo(s)
114+
115+
return {"scenario": s, "context": test_context}

0 commit comments

Comments
 (0)