Model/model_data/tests/test_wall_recommendations.py
2023-06-23 14:31:09 +01:00

182 lines
8.6 KiB
Python

import os
import pytest
import pickle
from unittest.mock import Mock
from model_data.recommendations.WallRecommendations import WallRecommendations
class TestWallRecommendations:
@pytest.fixture
def input_properties(self):
with open(
os.path.abspath(os.path.dirname(__file__)) + "/test_data/input_properties.pkl", "rb"
) as f:
return pickle.load(f)
@pytest.fixture
def uvalue_estimates(self):
with open(
os.path.abspath(os.path.dirname(__file__)) + "/test_data/uvalue_estimates_walls.pkl", "rb"
) as f:
return pickle.load(f)
@pytest.fixture
def mock_wall_rec_instance(self):
# Creating a mock instance of WallRecommendations with the necessary attributes
property_mock = Mock()
property_mock.full_sap_epc = {"lodgement-date": "2000-01-01"} # or any date you want
property_mock.data = {"construction-age-band": "1950"} # or any other data that fits your tests
uvalue_estimates_mock = Mock()
mock_wall_rec_instance = WallRecommendations(property_mock, uvalue_estimates_mock)
return mock_wall_rec_instance
def test_init(self, input_properties, uvalue_estimates):
obj = WallRecommendations(property_instance=input_properties[0], uvalue_estimates=uvalue_estimates)
assert obj
assert obj.property
assert obj.uvalue_estimates
assert obj.year_built == 2014
def test_uvalue_0_16(self, input_properties, uvalue_estimates):
"""
This tests the wall description Average thermal transmittance 0.16 W/m-¦K
The important data for this recommendation is:
- u value of 0.16
- property built in 2014
Since properties built after 1990 are typically built with insulation and this property
already has really good insulation, we do NOT recommend any measures for this property
"""
recommender = WallRecommendations(property_instance=input_properties[0], uvalue_estimates=uvalue_estimates)
assert recommender.property.walls["original_description"] == "Average thermal transmittance 0.16 W/m-¦K"
assert recommender.year_built == 2014
recommender.recommend()
# This should be empty
assert recommender.recommendations == []
def test_solid_brick_no_insulation(self, input_properties, uvalue_estimates):
"""
This tests a property with a wall description of Solid brick, as built, no insulation (assumed)
The property was built in 1930, right on the threshold for when cavity walls were introduced
However, we're told this property is solid brik so we assume no cavity.
We're also told that it has no insulation, so we will recommend internal/external wall insulation
This property is not in a conservation area, however it's a flat so we don't recommend external wall insulation
"""
recommender = WallRecommendations(property_instance=input_properties[1], uvalue_estimates=uvalue_estimates)
assert recommender.property.walls["original_description"] == "Solid brick, as built, no insulation (assumed)"
assert recommender.year_built == 1930
assert not recommender.ewi_valid
assert recommender.property.in_conservation_area == "not_in_conservation_area"
assert recommender.property.data["property-type"] == "Flat"
recommender.recommend()
# This should result in some recommendations, all of which should be internal insulation
assert recommender.recommendations
rec_types = {rec["type"] for rec in recommender.recommendations}
assert rec_types == {"internal_wall_insulation"}
# Check the recommendations provide a u value below the minimum
assert all(
rec["new_u_value"] < WallRecommendations.BUILDING_REGULATIONS_PART_L_MAX_U_VALUE for rec in
recommender.recommendations
)
def test_solid_brick_insulation(self, input_properties, uvalue_estimates):
"""
This tests a property with a wall description of Solid brick, as built, insulation (assumed)
The property was built in 1991, after cavity walls were introduced
However, we're told this property is solid brik so we assume no cavity.
We're also told that it has some insulation already
We'll need to estimate the u-value for this property since we don't know what the insulation is
and how thick it is. We'll estimate the u-value based on similar properties, by matching properties
with similar attributes such as the walls energy efficiency rating, the property type, the number of rooms,
etc
This property is not in a conservation area, however it's a flat so we don't recommend external wall insulation
"""
recommender = WallRecommendations(property_instance=input_properties[6], uvalue_estimates=uvalue_estimates)
assert recommender.property.walls["original_description"] == "Solid brick, as built, insulated (assumed)"
assert recommender.year_built == 1991
assert not recommender.ewi_valid
assert recommender.property.in_conservation_area == "not_in_conservation_area"
assert recommender.property.data["property-type"] == "Flat"
assert recommender.estimated_u_value is None
recommender.recommend()
# We should result in some recommendations, all of which should be internal wall insulation
assert recommender.recommendations
assert recommender.estimated_u_value == 0.45
rec_types = {rec["type"] for rec in recommender.recommendations}
assert rec_types == {"internal_wall_insulation"}
# Check the recommendations provide a u value below the minimum
assert all(
rec["new_u_value"] < WallRecommendations.BUILDING_REGULATIONS_PART_L_MAX_U_VALUE for rec in
recommender.recommendations
)
for rec in recommender.recommendations:
assert rec["new_u_value"] < 0.3
def test_is_diminishing_returns_no_recommendations(self, mock_wall_rec_instance):
# We have no recommendations but the new u value is below the diminishing returns threshold
# however since there are no recommendaions yet, we should include it and say
# it is NOT diminishing
mock_wall_rec_instance.recommendations = []
new_u_value = 0.24
assert new_u_value < WallRecommendations.DIMINISHING_RETURNS_U_VALUE
assert not mock_wall_rec_instance._is_diminishing_returns(new_u_value, None)
def test_is_diminishing_returns_diminishing(self, mock_wall_rec_instance):
# We have a recommendation already and the new u value falls below the diminishing returns
# threshold and is also lower than the lowest selected u value, so we should say this IS
# diminishing returns
mock_wall_rec_instance.recommendations = [Mock()]
new_u_value = 0.2
lowest_selected_u_value = 0.23
assert new_u_value < WallRecommendations.DIMINISHING_RETURNS_U_VALUE
assert mock_wall_rec_instance._is_diminishing_returns(new_u_value, lowest_selected_u_value)
def test_is_diminishing_returns_is_diminishing(self, mock_wall_rec_instance):
# We have a recommendation already and the new u value falls below the diminishing returns
# threshold and it's lower than the lowest selected u value, so we should say this IS DIMINISHIN
mock_wall_rec_instance.recommendations = [Mock()]
new_u_value = 0.24
lowest_selected_u_value = 0.26
assert new_u_value < WallRecommendations.DIMINISHING_RETURNS_U_VALUE
assert mock_wall_rec_instance._is_diminishing_returns(new_u_value, lowest_selected_u_value)
def test_is_diminishing_returns_not_diminishing(self, mock_wall_rec_instance):
# We have a recommendation already and the new u value falls below the diminishing returns
# threshold however it's higher than the lowest selected u value, so we should say this is NOT
# diminishing returns
mock_wall_rec_instance.recommendations = [Mock()]
new_u_value = 0.24
lowest_selected_u_value = 0.22
assert new_u_value < WallRecommendations.DIMINISHING_RETURNS_U_VALUE
assert not mock_wall_rec_instance._is_diminishing_returns(new_u_value, lowest_selected_u_value)
def test_is_diminishing_returns_error_in_recommendations(self, mock_wall_rec_instance):
# Testing case where there's an error in recommendations
mock_wall_rec_instance.recommendations = []
with pytest.raises(ValueError):
mock_wall_rec_instance._is_diminishing_returns(0.2, 0.24)