From 1d82433b066d8eacab88ad005339761f5ac1c852 Mon Sep 17 00:00:00 2001 From: Khalim Conn-Kowlessar Date: Thu, 22 Aug 2024 08:44:38 +0100 Subject: [PATCH] heating recs testing wip --- .../test_data/heating_recommendations_data.py | 60 +++++++++++++++++++ .../tests/test_heating_recommendations.py | 51 ++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 recommendations/tests/test_data/heating_recommendations_data.py create mode 100644 recommendations/tests/test_heating_recommendations.py diff --git a/recommendations/tests/test_data/heating_recommendations_data.py b/recommendations/tests/test_data/heating_recommendations_data.py new file mode 100644 index 00000000..3cb80876 --- /dev/null +++ b/recommendations/tests/test_data/heating_recommendations_data.py @@ -0,0 +1,60 @@ +import random +from pathlib import Path +import inspect +import pandas as pd + +# this can be used to get example data to build the test cases +src_file_path = inspect.getfile(lambda: None) +EPC_DIRECTORY = Path(src_file_path).parent / "local_data" / "all-domestic-certificates" +epc_directories = [entry for entry in EPC_DIRECTORY.iterdir() if entry.is_dir()] +directory = random.sample(epc_directories, 1)[0] +data = pd.read_csv(directory / "certificates.csv", low_memory=False) +# Rename the columns to the same format as the api returns +data.columns = [c.replace("_", "-").lower() for c in data.columns] + +eg = data.sample(1).to_dict("records")[0] + +testing_examples = [ + { + "epc": { + 'lmk-key': '948324269042014090409224502942098', 'address1': '15, Ringwood Crescent', 'address2': None, + 'address3': None, 'postcode': 'TS19 9DN', 'building-reference-number': 1016769078, + 'current-energy-rating': 'C', 'potential-energy-rating': 'B', 'current-energy-efficiency': 79, + 'potential-energy-efficiency': 85, 'property-type': 'House', 'built-form': 'Semi-Detached', + 'inspection-date': '2014-08-21', 'local-authority': 'E06000004', 'constituency': 'E14000970', + 'county': None, + 'lodgement-date': '2014-09-04', 'transaction-type': 'none of the above', 'environment-impact-current': 77, + 'environment-impact-potential': 85, 'energy-consumption-current': 152, + 'energy-consumption-potential': 103.0, 'co2-emissions-current': 2.2, 'co2-emiss-curr-per-floor-area': 30, + 'co2-emissions-potential': 1.5, 'lighting-cost-current': 61.0, 'lighting-cost-potential': 47.0, + 'heating-cost-current': 625.0, 'heating-cost-potential': 522.0, 'hot-water-cost-current': 100.0, + 'hot-water-cost-potential': 71.0, 'total-floor-area': 74.0, 'energy-tariff': 'Single', + 'mains-gas-flag': 'Y', 'floor-level': 'NODATA!', 'flat-top-storey': None, 'flat-storey-count': None, + 'main-heating-controls': 2106.0, 'multi-glaze-proportion': 100.0, + 'glazed-type': 'double glazing installed before 2002', 'glazed-area': 'Normal', 'extension-count': 0.0, + 'number-habitable-rooms': 3.0, 'number-heated-rooms': 3.0, 'low-energy-lighting': 70.0, + 'number-open-fireplaces': 0.0, 'hotwater-description': 'From main system', 'hot-water-energy-eff': 'Good', + 'hot-water-env-eff': 'Good', 'floor-description': 'Solid, no insulation (assumed)', + 'floor-energy-eff': None, + 'floor-env-eff': None, 'windows-description': 'Fully double glazed', 'windows-energy-eff': 'Average', + 'windows-env-eff': 'Average', 'walls-description': 'Cavity wall, filled cavity', 'walls-energy-eff': 'Good', + 'walls-env-eff': 'Good', 'secondheat-description': 'Room heaters, mains gas', 'sheating-energy-eff': None, + 'sheating-env-eff': None, 'roof-description': 'Pitched, 50 mm loft insulation', 'roof-energy-eff': 'Poor', + 'roof-env-eff': 'Poor', 'mainheat-description': 'Boiler and radiators, mains gas', + 'mainheat-energy-eff': 'Good', 'mainheat-env-eff': 'Good', + 'mainheatcont-description': 'Programmer, room thermostat and TRVs', 'mainheatc-energy-eff': 'Good', + 'mainheatc-env-eff': 'Good', 'lighting-description': 'Low energy lighting in 70% of fixed outlets', + 'lighting-energy-eff': 'Very Good', 'lighting-env-eff': 'Very Good', + 'main-fuel': 'mains gas (not community)', 'wind-turbine-count': 0.0, 'heat-loss-corridor': 'NO DATA!', + 'unheated-corridor-length': None, 'floor-height': 2.5, 'photo-supply': 50.0, + 'solar-water-heating-flag': None, + 'mechanical-ventilation': 'natural', 'address': '15, Ringwood Crescent', + 'local-authority-label': 'Stockton-on-Tees', 'constituency-label': 'Stockton North', + 'posttown': 'STOCKTON-ON-TEES', 'construction-age-band': 'England and Wales: 1950-1966', + 'lodgement-datetime': '2014-09-04 09:22:45', 'tenure': 'owner-occupied', + 'fixed-lighting-outlets-count': 10.0, 'low-energy-fixed-light-count': 7.0, 'uprn': 100110195416.0, + 'uprn-source': 'Address Matched' + } + + } +] diff --git a/recommendations/tests/test_heating_recommendations.py b/recommendations/tests/test_heating_recommendations.py new file mode 100644 index 00000000..8857c343 --- /dev/null +++ b/recommendations/tests/test_heating_recommendations.py @@ -0,0 +1,51 @@ +import pandas as pd +from utils.s3 import read_dataframe_from_s3_parquet +import pytest +from backend.Property import Property +from etl.epc.Record import EPCRecord +from recommendations.HeatingRecommender import HeatingRecommender +from recommendations.tests.test_data.heating_recommendations_data import testing_examples + + +class TestHeatingRecommendations: + + @pytest.fixture + def cleaning_data(self): + return read_dataframe_from_s3_parquet( + bucket_name="retrofit-data-dev", file_key="sap_change_model/cleaning_dataset.parquet", + ) + + @pytest.mark.parametrize( + "test_case", + testing_examples + ) + def test_recommend(self, test_case, cleaning_data): + """ + With this function, we test out multiple heating descriptions and check which recomendations + we retrieve alongside them + :return: + """ + + epc_records = {"original_epc": test_case["epc"], "full_sap_epc": {}, "old_data": []} + + epc_record = EPCRecord( + epc_records=epc_records, + run_mode="newdata", + cleaning_data=cleaning_data + ) + + p = Property( + id=0, + postcode=test_case["epc"]["postcode"], + address=test_case["epc"]["address"], + epc_record=epc_record + ) + + recommender = HeatingRecommender(property_instance=p) + # Check they're empty + assert not recommender.heating_recommendations + assert not recommender.heating_control_recommendations + + recommender.recommend(has_cavity_or_loft_recommendations=False) + + # TODO: We check results against expected behaviour