Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
SimStadt
simstadtpy
Commits
b679af18
Commit
b679af18
authored
Mar 12, 2026
by
Eric Duminil
Browse files
Updated tests
parent
ec73c2cb
Changes
2
Hide whitespace changes
Inline
Side-by-side
src/simstadt/results.py
View file @
b679af18
...
@@ -481,10 +481,11 @@ class SolarPotentialResults(SimStadtResults):
...
@@ -481,10 +481,11 @@ class SolarPotentialResults(SimStadtResults):
def
kpis
(
self
)
->
list
[
KPI
]:
def
kpis
(
self
)
->
list
[
KPI
]:
df
=
self
.
dataframe
df
=
self
.
dataframe
return
[
return
[
#TODO: Add averages too?
KPI
(
"Annual GHI"
,
df
[
"GHI"
].
sum
()
/
1000
,
"kWh/m²"
,
precision
=
1
),
KPI
(
"Annual GHI"
,
df
[
"GHI"
].
sum
()
/
1000
,
"kWh/m²"
,
precision
=
1
),
KPI
(
"Average GHI"
,
df
[
"GHI"
].
mean
(),
"W/m²"
,
precision
=
1
),
KPI
(
"Annual DHI"
,
df
[
"DHI"
].
sum
()
/
1000
,
"kWh/m²"
,
precision
=
1
),
KPI
(
"Annual DHI"
,
df
[
"DHI"
].
sum
()
/
1000
,
"kWh/m²"
,
precision
=
1
),
KPI
(
"Mean temperature"
,
float
(
df
[
"Ta"
].
mean
()),
"°C"
,
precision
=
1
),
KPI
(
"Average DHI"
,
df
[
"DHI"
].
mean
(),
"W/m²"
,
precision
=
1
),
KPI
(
"Average temperature"
,
float
(
df
[
"Ta"
].
mean
()),
"°C"
,
precision
=
1
),
]
]
...
...
tests/test_results.py
View file @
b679af18
...
@@ -6,9 +6,9 @@ import pandas as pd
...
@@ -6,9 +6,9 @@ import pandas as pd
import
pytest
import
pytest
from
simstadt
import
(
from
simstadt
import
(
KPI
,
GreenWaterResults
,
GreenWaterResults
,
HeatDemandResults
,
HeatDemandResults
,
KPI
,
LoadProfileResults
,
LoadProfileResults
,
PhotovoltaicResults
,
PhotovoltaicResults
,
SimStadtResults
,
SimStadtResults
,
...
@@ -38,12 +38,16 @@ def find_output_files(workflow_name: str) -> list[Path]:
...
@@ -38,12 +38,16 @@ def find_output_files(workflow_name: str) -> list[Path]:
# Heat demand (heating only)
# Heat demand (heating only)
# ---------------------------------------------------------------------------
# ---------------------------------------------------------------------------
@
pytest
.
fixture
(
scope
=
"module"
)
@
pytest
.
fixture
(
scope
=
"module"
)
def
heating_results
()
->
SimStadtResults
:
def
heating_results
()
->
SimStadtResults
:
output_files
=
[
output_files
=
[
TEST_REPOSITORY
/
"CGSC.proj/101_HeatDemand.flow/02_WeatherProcessor.step/hourly_GHI_DHI_Ta_meteonorm_Wuerzburg.prn"
,
TEST_REPOSITORY
TEST_REPOSITORY
/
"CGSC.proj/101_HeatDemand.flow/04_MonthlyEnergyBalance.step/Grombuehl_mini_Steinheilstrasse_DIN18599_HEATING.csv"
,
/
"CGSC.proj/101_HeatDemand.flow/02_WeatherProcessor.step/hourly_GHI_DHI_Ta_meteonorm_Wuerzburg.prn"
,
TEST_REPOSITORY
/
"CGSC.proj/101_HeatDemand.flow/04_MonthlyEnergyBalance.step/Grombuehl_mini_Steinheilstrasse_DIN18599_HEATING.log"
,
TEST_REPOSITORY
/
"CGSC.proj/101_HeatDemand.flow/04_MonthlyEnergyBalance.step/Grombuehl_mini_Steinheilstrasse_DIN18599_HEATING.csv"
,
TEST_REPOSITORY
/
"CGSC.proj/101_HeatDemand.flow/04_MonthlyEnergyBalance.step/Grombuehl_mini_Steinheilstrasse_DIN18599_HEATING.log"
,
]
]
return
create_simstadt_results
(
"Heat demand simulation for Grombühl"
,
output_files
)
return
create_simstadt_results
(
"Heat demand simulation for Grombühl"
,
output_files
)
...
@@ -93,7 +97,10 @@ def test_heating_kpis(heating_results):
...
@@ -93,7 +97,10 @@ def test_heating_kpis(heating_results):
assert
kpis
[
"Storey number"
].
value
==
pytest
.
approx
(
4
,
abs
=
0.5
)
assert
kpis
[
"Storey number"
].
value
==
pytest
.
approx
(
4
,
abs
=
0.5
)
assert
kpis
[
"Year of construction"
].
value
==
pytest
.
approx
(
1963
,
abs
=
0.5
)
assert
kpis
[
"Year of construction"
].
value
==
pytest
.
approx
(
1963
,
abs
=
0.5
)
assert
heating_results
.
kpi
(
"Number of buildings"
).
value
==
24
assert
heating_results
.
kpi
(
"Number of buildings"
).
value
==
24
assert
heating_results
.
kpi
(
"Specific Heating Demand"
).
value
==
pytest
.
approx
(
100
,
abs
=
5
)
assert
heating_results
.
kpi
(
"Number of buildings"
).
unit
is
None
assert
heating_results
.
kpi
(
"Specific Heating Demand"
).
value
==
pytest
.
approx
(
100
,
abs
=
5
)
with
pytest
.
raises
(
ValueError
,
match
=
"No 'Not here' KPI found"
):
with
pytest
.
raises
(
ValueError
,
match
=
"No 'Not here' KPI found"
):
heating_results
.
kpi
(
"Not here"
)
heating_results
.
kpi
(
"Not here"
)
assert
len
(
kpis
)
==
10
# heating only
assert
len
(
kpis
)
==
10
# heating only
...
@@ -139,33 +146,36 @@ def test_heating_repr(heating_results):
...
@@ -139,33 +146,36 @@ def test_heating_repr(heating_results):
# ---------------------------------------------------------------------------
# ---------------------------------------------------------------------------
# Heat + cool demand
# Heat
ing
+ cool
ing
demand
# ---------------------------------------------------------------------------
# ---------------------------------------------------------------------------
@
pytest
.
fixture
(
scope
=
"module"
)
@
pytest
.
fixture
(
scope
=
"module"
)
def
heat_cool_results
()
->
SimStadtResults
:
def
heat
ing_and
_cool
ing
_results
()
->
SimStadtResults
:
return
create_simstadt_results
(
return
create_simstadt_results
(
"Heating and cooling demand simulation for Grombühl"
,
"Heating and cooling demand simulation for Grombühl"
,
find_output_files
(
"104_HeatAndCoolDemand.flow"
),
find_output_files
(
"104_HeatAndCoolDemand.flow"
),
)
)
def
test_heating_cool_result_type
(
heat_cool_results
):
def
test_heating_
and_
cool
ing
_result_type
(
heat
ing_and
_cool
ing
_results
):
assert
isinstance
(
heat_cool_results
,
HeatDemandResults
)
assert
isinstance
(
heat
ing_and
_cool
ing
_results
,
HeatDemandResults
)
def
test_heating_cool_kpis
(
heat_cool_results
):
def
test_heating_
and_
cool
ing
_kpis
(
heat
ing_and
_cool
ing
_results
):
kpis
=
kpis_by_name
(
heat_cool_results
)
kpis
=
kpis_by_name
(
heat
ing_and
_cool
ing
_results
)
assert
"Yearly Heating demand"
in
kpis
assert
"Yearly Heating demand"
in
kpis
assert
"Specific Heating Demand"
in
kpis
assert
"Specific Heating Demand"
in
kpis
assert
"Yearly Cooling demand"
in
kpis
assert
"Yearly Cooling demand"
in
kpis
assert
"Specific Cooling Demand"
in
kpis
assert
"Specific Cooling Demand"
in
kpis
assert
heat_cool_results
.
kpi
(
"Specific Cooling Demand"
).
value
==
pytest
.
approx
(
20
,
abs
=
1
)
assert
heating_and_cooling_results
.
kpi
(
"Specific Cooling Demand"
).
value
==
pytest
.
approx
(
20
,
abs
=
1
)
assert
len
(
kpis
)
==
12
assert
len
(
kpis
)
==
12
def
test_heating_cool_diagrams
(
heat_cool_results
):
def
test_heating_
and_
cool
ing
_diagrams
(
heat
ing_and
_cool
ing
_results
):
diagrams
=
heat_cool_results
.
diagrams
diagrams
=
heat
ing_and
_cool
ing
_results
.
diagrams
assert
len
(
diagrams
)
>
0
assert
len
(
diagrams
)
>
0
assert
"Monthly demands"
in
diagrams
assert
"Monthly demands"
in
diagrams
for
diagram
in
diagrams
.
values
():
for
diagram
in
diagrams
.
values
():
...
@@ -176,6 +186,7 @@ def test_heating_cool_diagrams(heat_cool_results):
...
@@ -176,6 +186,7 @@ def test_heating_cool_diagrams(heat_cool_results):
# Cooling only
# Cooling only
# ---------------------------------------------------------------------------
# ---------------------------------------------------------------------------
@
pytest
.
fixture
(
scope
=
"module"
)
@
pytest
.
fixture
(
scope
=
"module"
)
def
cooling_results
()
->
SimStadtResults
:
def
cooling_results
()
->
SimStadtResults
:
return
create_simstadt_results
(
return
create_simstadt_results
(
...
@@ -203,11 +214,14 @@ def test_cooling_kpis(cooling_results):
...
@@ -203,11 +214,14 @@ def test_cooling_kpis(cooling_results):
# Green water
# Green water
# ---------------------------------------------------------------------------
# ---------------------------------------------------------------------------
@
pytest
.
fixture
(
scope
=
"module"
)
@
pytest
.
fixture
(
scope
=
"module"
)
def
greenwater_results
()
->
SimStadtResults
:
def
greenwater_results
()
->
SimStadtResults
:
output_files
=
[
output_files
=
[
TEST_REPOSITORY
/
"CGSC.proj/102_GreenWater.flow/02_WeatherProcessor.step/hourly_GHI_DHI_Ta_meteonorm_Wuerzburg.prn"
,
TEST_REPOSITORY
TEST_REPOSITORY
/
"CGSC.proj/102_GreenWater.flow/03_GreenWater.step/Grombühl_mini_with_trees_greenwater.csv"
,
/
"CGSC.proj/102_GreenWater.flow/02_WeatherProcessor.step/hourly_GHI_DHI_Ta_meteonorm_Wuerzburg.prn"
,
TEST_REPOSITORY
/
"CGSC.proj/102_GreenWater.flow/03_GreenWater.step/Grombühl_mini_with_trees_greenwater.csv"
,
]
]
return
create_simstadt_results
(
"Green Water simulation for Grombühl"
,
output_files
)
return
create_simstadt_results
(
"Green Water simulation for Grombühl"
,
output_files
)
...
@@ -321,11 +335,14 @@ def test_greenwater_repr(greenwater_results):
...
@@ -321,11 +335,14 @@ def test_greenwater_repr(greenwater_results):
# Photovoltaic
# Photovoltaic
# ---------------------------------------------------------------------------
# ---------------------------------------------------------------------------
@
pytest
.
fixture
(
scope
=
"module"
)
@
pytest
.
fixture
(
scope
=
"module"
)
def
pv_results
()
->
SimStadtResults
:
def
pv_results
()
->
SimStadtResults
:
output_files
=
[
output_files
=
[
TEST_REPOSITORY
/
"CGSC.proj/103_PV.flow/02_WeatherProcessor.step/hourly_GHI_DHI_Ta_meteonorm_Wuerzburg.prn"
,
TEST_REPOSITORY
TEST_REPOSITORY
/
"CGSC.proj/103_PV.flow/04_PhotovoltaicPotential.step/Grombühl_mini_with_trees_meteonorm_Hay_pv_potential.csv"
,
/
"CGSC.proj/103_PV.flow/02_WeatherProcessor.step/hourly_GHI_DHI_Ta_meteonorm_Wuerzburg.prn"
,
TEST_REPOSITORY
/
"CGSC.proj/103_PV.flow/04_PhotovoltaicPotential.step/Grombühl_mini_with_trees_meteonorm_Hay_pv_potential.csv"
,
]
]
return
create_simstadt_results
(
"PV for Grombühl"
,
output_files
)
return
create_simstadt_results
(
"PV for Grombühl"
,
output_files
)
...
@@ -409,10 +426,13 @@ def test_pv_no_log(pv_results):
...
@@ -409,10 +426,13 @@ def test_pv_no_log(pv_results):
# Edge cases
# Edge cases
# ---------------------------------------------------------------------------
# ---------------------------------------------------------------------------
def
test_greenwater_without_trees
():
def
test_greenwater_without_trees
():
output_files
=
[
output_files
=
[
TEST_REPOSITORY
/
"CGSC.proj/102_GreenWater.flow/02_WeatherProcessor.step/hourly_GHI_DHI_Ta_meteonorm_Wuerzburg.prn"
,
TEST_REPOSITORY
TEST_REPOSITORY
/
"CGSC.proj/102_GreenWater.flow/03_GreenWater.step/Grombühl_mini_greenwater.csv"
,
/
"CGSC.proj/102_GreenWater.flow/02_WeatherProcessor.step/hourly_GHI_DHI_Ta_meteonorm_Wuerzburg.prn"
,
TEST_REPOSITORY
/
"CGSC.proj/102_GreenWater.flow/03_GreenWater.step/Grombühl_mini_greenwater.csv"
,
]
]
results
=
create_simstadt_results
(
"Green Water without trees"
,
output_files
)
results
=
create_simstadt_results
(
"Green Water without trees"
,
output_files
)
with
pytest
.
raises
(
ValueError
,
match
=
"any tree"
):
with
pytest
.
raises
(
ValueError
,
match
=
"any tree"
):
...
@@ -425,10 +445,12 @@ def test_greenwater_without_trees():
...
@@ -425,10 +445,12 @@ def test_greenwater_without_trees():
# Load profile
# Load profile
# ---------------------------------------------------------------------------
# ---------------------------------------------------------------------------
@
pytest
.
fixture
(
scope
=
"module"
)
@
pytest
.
fixture
(
scope
=
"module"
)
def
loadprofile_results
()
->
SimStadtResults
:
def
loadprofile_results
()
->
SimStadtResults
:
output_files
=
[
output_files
=
[
LOAD_PROFILE_FLOW
/
"02_LoadProfileGenerator.step/MiniBuchwald_load_profile_Hourly.csv"
,
LOAD_PROFILE_FLOW
/
"02_LoadProfileGenerator.step/MiniBuchwald_load_profile_Hourly.csv"
,
]
]
return
create_simstadt_results
(
"Load profile for MiniBuchwald"
,
output_files
)
return
create_simstadt_results
(
"Load profile for MiniBuchwald"
,
output_files
)
...
@@ -475,7 +497,10 @@ def test_loadprofile_project(loadprofile_results):
...
@@ -475,7 +497,10 @@ def test_loadprofile_project(loadprofile_results):
def
test_loadprofile_params
(
loadprofile_results
):
def
test_loadprofile_params
(
loadprofile_results
):
assert
loadprofile_results
.
short_name
==
"LoadProfile"
assert
loadprofile_results
.
short_name
==
"LoadProfile"
assert
loadprofile_results
.
name
==
"LoadProfile_Template"
assert
loadprofile_results
.
name
==
"LoadProfile_Template"
assert
loadprofile_results
.
workflow_provider
==
"de.hftstuttgart.simstadtworkflows.energy.LoadProfileProvider"
assert
(
loadprofile_results
.
workflow_provider
==
"de.hftstuttgart.simstadtworkflows.energy.LoadProfileProvider"
)
def
test_loadprofile_serialization
(
loadprofile_results
):
def
test_loadprofile_serialization
(
loadprofile_results
):
...
@@ -485,7 +510,9 @@ def test_loadprofile_serialization(loadprofile_results):
...
@@ -485,7 +510,9 @@ def test_loadprofile_serialization(loadprofile_results):
assert
reconstructed
.
description
==
loadprofile_results
.
description
assert
reconstructed
.
description
==
loadprofile_results
.
description
assert
len
(
reconstructed
.
output_files
)
==
len
(
loadprofile_results
.
output_files
)
assert
len
(
reconstructed
.
output_files
)
==
len
(
loadprofile_results
.
output_files
)
assert
len
(
reconstructed
.
kpis
)
==
3
assert
len
(
reconstructed
.
kpis
)
==
3
pd
.
testing
.
assert_frame_equal
(
reconstructed
.
dataframe
,
loadprofile_results
.
dataframe
)
pd
.
testing
.
assert_frame_equal
(
reconstructed
.
dataframe
,
loadprofile_results
.
dataframe
)
def
test_loadprofile_repr
(
loadprofile_results
):
def
test_loadprofile_repr
(
loadprofile_results
):
...
@@ -498,6 +525,7 @@ def test_loadprofile_repr(loadprofile_results):
...
@@ -498,6 +525,7 @@ def test_loadprofile_repr(loadprofile_results):
# Solar potential
# Solar potential
# ---------------------------------------------------------------------------
# ---------------------------------------------------------------------------
@
pytest
.
fixture
(
scope
=
"module"
)
@
pytest
.
fixture
(
scope
=
"module"
)
def
solar_results
()
->
SimStadtResults
:
def
solar_results
()
->
SimStadtResults
:
output_files
=
[
output_files
=
[
...
@@ -525,9 +553,18 @@ def test_solar_kpis(solar_results):
...
@@ -525,9 +553,18 @@ def test_solar_kpis(solar_results):
kpis
=
kpis_by_name
(
solar_results
)
kpis
=
kpis_by_name
(
solar_results
)
assert
kpis
[
"Annual GHI"
].
value
==
pytest
.
approx
(
1143.9
,
abs
=
0.1
)
assert
kpis
[
"Annual GHI"
].
value
==
pytest
.
approx
(
1143.9
,
abs
=
0.1
)
assert
kpis
[
"Annual GHI"
].
unit
==
"kWh/m²"
assert
kpis
[
"Annual GHI"
].
unit
==
"kWh/m²"
assert
kpis
[
"Average GHI"
].
value
==
pytest
.
approx
(
130
,
abs
=
1
)
assert
kpis
[
"Average GHI"
].
unit
==
"W/m²"
assert
kpis
[
"Annual DHI"
].
value
==
pytest
.
approx
(
685.1
,
abs
=
0.1
)
assert
kpis
[
"Annual DHI"
].
value
==
pytest
.
approx
(
685.1
,
abs
=
0.1
)
assert
kpis
[
"Mean temperature"
].
value
==
pytest
.
approx
(
9.73
,
abs
=
0.05
)
assert
kpis
[
"Annual DHI"
].
unit
==
"kWh/m²"
assert
kpis
[
"Mean temperature"
].
unit
==
"°C"
assert
kpis
[
"Average DHI"
].
value
==
pytest
.
approx
(
78
,
abs
=
1
)
assert
kpis
[
"Average DHI"
].
unit
==
"W/m²"
assert
kpis
[
"Average temperature"
].
value
==
pytest
.
approx
(
9.73
,
abs
=
0.05
)
assert
kpis
[
"Average temperature"
].
unit
==
"°C"
def
test_solar_no_diagrams
(
solar_results
):
def
test_solar_no_diagrams
(
solar_results
):
...
@@ -551,7 +588,7 @@ def test_solar_serialization(solar_results):
...
@@ -551,7 +588,7 @@ def test_solar_serialization(solar_results):
reconstructed
=
SimStadtResults
.
from_json
(
json_str
)
reconstructed
=
SimStadtResults
.
from_json
(
json_str
)
assert
isinstance
(
reconstructed
,
SolarPotentialResults
)
assert
isinstance
(
reconstructed
,
SolarPotentialResults
)
assert
reconstructed
.
description
==
solar_results
.
description
assert
reconstructed
.
description
==
solar_results
.
description
assert
len
(
reconstructed
.
kpis
)
==
3
assert
len
(
reconstructed
.
kpis
)
==
5
pd
.
testing
.
assert_frame_equal
(
reconstructed
.
dataframe
,
solar_results
.
dataframe
)
pd
.
testing
.
assert_frame_equal
(
reconstructed
.
dataframe
,
solar_results
.
dataframe
)
...
@@ -563,8 +600,10 @@ def test_solar_repr(solar_results):
...
@@ -563,8 +600,10 @@ def test_solar_repr(solar_results):
def
test_broken_simulation
():
def
test_broken_simulation
():
output_files
=
[
output_files
=
[
TEST_REPOSITORY
/
"CGSC.proj/103_PV.flow/02_WeatherProcessor.step/notATable.log"
,
TEST_REPOSITORY
TEST_REPOSITORY
/
"CGSC.proj/103_PV.flow/04_PhotovoltaicPotential.step/StillNotATable.png"
,
/
"CGSC.proj/103_PV.flow/02_WeatherProcessor.step/notATable.log"
,
TEST_REPOSITORY
/
"CGSC.proj/103_PV.flow/04_PhotovoltaicPotential.step/StillNotATable.png"
,
]
]
results
=
create_simstadt_results
(
"FakeTests"
,
output_files
)
results
=
create_simstadt_results
(
"FakeTests"
,
output_files
)
with
pytest
.
raises
(
ValueError
,
match
=
"any CSV file"
):
with
pytest
.
raises
(
ValueError
,
match
=
"any CSV file"
):
...
@@ -572,4 +611,4 @@ def test_broken_simulation():
...
@@ -572,4 +611,4 @@ def test_broken_simulation():
with
pytest
.
raises
(
ValueError
,
match
=
"any CSV file"
):
with
pytest
.
raises
(
ValueError
,
match
=
"any CSV file"
):
results
.
to_json
()
results
.
to_json
()
with
pytest
.
raises
(
ValueError
,
match
=
"any CSV file"
):
with
pytest
.
raises
(
ValueError
,
match
=
"any CSV file"
):
_
=
results
.
kpis
results
.
kpis
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment