From 814cd636102ad959592600c8b8281584f8f7e896 Mon Sep 17 00:00:00 2001 From: fleimgruber Date: Wed, 15 Sep 2021 17:30:22 +0200 Subject: [PATCH] test: smoke tests for Raw and Pandas clients --- tests/test_clients.py | 113 ---------------------------- tests/test_domains.py | 48 ------------ tests/test_pandas.py | 146 ++++++++++++++++++++++++++++++++++++ tests/test_raw.py | 171 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 317 insertions(+), 161 deletions(-) delete mode 100644 tests/test_clients.py delete mode 100644 tests/test_domains.py create mode 100644 tests/test_pandas.py create mode 100644 tests/test_raw.py diff --git a/tests/test_clients.py b/tests/test_clients.py deleted file mode 100644 index 142449d..0000000 --- a/tests/test_clients.py +++ /dev/null @@ -1,113 +0,0 @@ -import unittest - -import pandas as pd -from bs4 import BeautifulSoup - -from entsoe import EntsoeRawClient, EntsoePandasClient -from entsoe.exceptions import NoMatchingDataError -from settings import api_key - - -class EntsoeRawClientTest(unittest.TestCase): - @classmethod - def setUpClass(cls): - cls.client = EntsoeRawClient(api_key=api_key) - cls.start = pd.Timestamp('20180101', tz='Europe/Brussels') - cls.end = pd.Timestamp('20180107', tz='Europe/Brussels') - cls.country_code = 'BE' - - def test_datetime_to_str(self): - start_str = self.client._datetime_to_str(dtm=self.start) - self.assertIsInstance(start_str, str) - self.assertEqual(start_str, '201712312300') - - def test_basic_queries(self): - queries = [ - self.client.query_day_ahead_prices, - self.client.query_load, - self.client.query_wind_and_solar_forecast, - self.client.query_load_forecast, - self.client.query_generation, - self.client.query_generation_forecast, - self.client.query_installed_generation_capacity, - self.client.query_imbalance_prices - ] - for query in queries: - text = query(country_code=self.country_code, start=self.start, - end=self.end) - self.assertIsInstance(text, str) - try: - BeautifulSoup(text, 'html.parser') - except Exception as e: - self.fail(f'Parsing of response failed with exception: {e}') - - def query_crossborder_flows(self): - text = self.client.query_crossborder_flows( - country_code_from='BE', country_code_to='NL', start=self.start, - end=self.end) - self.assertIsInstance(text, str) - try: - BeautifulSoup(text, 'html.parser') - except Exception as e: - self.fail(f'Parsing of response failed with exception: {e}') - - def test_query_unavailability_of_generation_units(self): - text = self.client.query_unavailability_of_generation_units( - country_code='BE', start=self.start, - end=self.end) - self.assertIsInstance(text, bytes) - - def test_query_withdrawn_unavailability_of_generation_units(self): - with self.assertRaises(NoMatchingDataError): - self.client.query_withdrawn_unavailability_of_generation_units( - country_code='BE', start=self.start, end=self.end) - - -class EntsoePandasClientTest(EntsoeRawClientTest): - @classmethod - def setUpClass(cls): - cls.client = EntsoePandasClient(api_key=api_key) - cls.start = pd.Timestamp('20180101', tz='Europe/Brussels') - cls.end = pd.Timestamp('20180107', tz='Europe/Brussels') - cls.country_code = 'BE' - - def test_basic_queries(self): - pass - - def test_basic_series(self): - queries = [ - self.client.query_day_ahead_prices, - self.client.query_load, - self.client.query_load_forecast, - self.client.query_generation_forecast - ] - for query in queries: - ts = query(country_code=self.country_code, start=self.start, - end=self.end) - self.assertIsInstance(ts, pd.Series) - - def query_crossborder_flows(self): - ts = self.client.query_crossborder_flows( - country_code_from='BE', country_code_to='NL', start=self.start, - end=self.end) - self.assertIsInstance(ts, pd.Series) - - def test_basic_dataframes(self): - queries = [ - self.client.query_wind_and_solar_forecast, - self.client.query_generation, - self.client.query_installed_generation_capacity, - self.client.query_imbalance_prices, - self.client.query_unavailability_of_generation_units, - ] - for query in queries: - ts = query(country_code=self.country_code, start=self.start, - end=self.end) - self.assertIsInstance(ts, pd.DataFrame) - - def test_query_unavailability_of_generation_units(self): - pass - - -if __name__ == '__main__': - unittest.main() \ No newline at end of file diff --git a/tests/test_domains.py b/tests/test_domains.py deleted file mode 100644 index 6f91a0c..0000000 --- a/tests/test_domains.py +++ /dev/null @@ -1,48 +0,0 @@ -import pandas as pd -from settings import api_key -from entsoe import EntsoeRawClient as Entsoe - - -def test_czech_unavailability_of_production_units(): - e = Entsoe(api_key=api_key, retry_count=20, retry_delay=30) - - start = pd.Timestamp("20170601", tz="Europe/Brussels") - end = pd.Timestamp("20170603", tz="Europe/Brussels") - - # s = e.query_imbalance_prices(country_code='BE', start=start, end=end, as_dataframe=True) - - """domains = [["10YIT-GRTN-----B", "Italy, IT CA / MBA"], - ["10Y1001A1001A885", "Italy_Saco_AC"], - ["10Y1001A1001A893", "Italy_Saco_DC"], - ["10Y1001A1001A699", "IT-Brindisi BZ"], - ["10Y1001A1001A70O", "IT-Centre-North BZ"], - ["10Y1001A1001A71M", "IT-Centre-South BZ"], - ["10Y1001A1001A72K", "IT-Foggia BZ"], - ["10Y1001A1001A66F", "IT-GR BZ"], - ["10Y1001A1001A84D", "IT-MACROZONE NORTH MBA"], - ["10Y1001A1001A85B", "IT-MACROZONE SOUTH MBA"], - ["10Y1001A1001A877", "IT-Malta BZ"], - ["10Y1001A1001A73I", "IT-North BZ"], - ["10Y1001A1001A80L", "IT-North-AT BZ"], - ["10Y1001A1001A68B", "IT-North-CH BZ"], - ["10Y1001A1001A81J", "IT-North-FR BZ"], - ["10Y1001A1001A67D", "IT-North-SI BZ"], - ["10Y1001A1001A76C", "IT-Priolo BZ"], - ["10Y1001A1001A77A", "IT-Rossano BZ"], - ["10Y1001A1001A74G", "IT-Sardinia BZ"], - ["10Y1001A1001A75E", "IT-Sicily BZ"], - ["10Y1001A1001A788", "IT-South BZ"]] - """ - - domains = [["CZ", "Czech bidding zone"]] - - lst = [] - for bzn in domains: - s = e.query_unavailability_of_production_units( - country_code=bzn[0], docstatus=None, start=start, end=end - ) - if s is not None: - lst.append(s) - - result = pd.concat(lst) - result.to_csv("result.csv") diff --git a/tests/test_pandas.py b/tests/test_pandas.py new file mode 100644 index 0000000..d42696b --- /dev/null +++ b/tests/test_pandas.py @@ -0,0 +1,146 @@ +from itertools import product + +from entsoe import EntsoePandasClient +import pandas as pd +import pytest + +from settings import api_key + + +@pytest.fixture +def client(): + yield EntsoePandasClient(api_key=api_key) + + +@pytest.fixture +def start(): + return pd.Timestamp("20171201", tz="Europe/Brussels") + + +@pytest.fixture +def end(): + return pd.Timestamp("20180101", tz="Europe/Brussels") + + +@pytest.fixture +def country_code(): + return "BE" # Belgium + + +@pytest.fixture +def country_code_from(): + return "FR" # France + + +@pytest.fixture +def country_code_to(): + return "DE_LU" # Germany-Luxembourg + + +STARTS = [pd.Timestamp("20171201", tz="Europe/Brussels")] +ENDS = [pd.Timestamp("20180101", tz="Europe/Brussels")] +COUNTRY_CODES = ["BE"] # Belgium +COUNTRY_CODES_FROM = ["FR"] # France +COUNTRY_CODES_TO = ["DE_LU"] # Germany-Luxembourg + +BASIC_QUERIES_SERIES = [ + "query_day_ahead_prices", + "query_net_position_dayahead", + "query_load", + "query_load_forecast", +] + +BASIC_QUERIES_DATAFRAME = [ + "query_wind_and_solar_forecast", + "query_generation_forecast", + "query_generation", + "query_generation_per_plant", + "query_installed_generation_capacity", + "query_installed_generation_capacity_per_unit", + "query_imbalance_prices", + "query_withdrawn_unavailability_of_generation_units", + "query_unavailability_of_generation_units", + "query_unavailability_of_production_units", + "query_import", + "query_generation_import", +] + +CROSSBORDER_QUERIES = [ + "query_crossborder_flows", + "query_scheduled_exchanges", + "query_net_transfer_capacity_dayahead", + "query_net_transfer_capacity_weekahead", + "query_net_transfer_capacity_monthahead", + "query_net_transfer_capacity_yearahead", + "query_intraday_offered_capacity", +] + +# pandas.Series + +@pytest.mark.parametrize( + "country_code, start, end, query", + product(COUNTRY_CODES, STARTS, ENDS, BASIC_QUERIES_SERIES), +) +def test_basic_queries_series(client, query, country_code, start, end): + result = getattr(client, query)(country_code, start=start, end=end) + assert not result.empty + + +@pytest.mark.parametrize( + "country_code_from, country_code_to, start, end, query", + product(COUNTRY_CODES_FROM, COUNTRY_CODES_TO, STARTS, ENDS, CROSSBORDER_QUERIES), +) +def test_crossborder_queries( + client, query, country_code_from, country_code_to, start, end +): + result = getattr(client, query)(country_code_from, country_code_to, start=start, end=end) + assert not result.empty + +# pandas.DataFrames + +@pytest.mark.parametrize( + "country_code, start, end, query", + product(COUNTRY_CODES, STARTS, ENDS, BASIC_QUERIES_DATAFRAME), +) +def test_basic_queries_dataframe(client, query, country_code, start, end): + result = getattr(client, query)(country_code, start=start, end=end) + assert not result.empty + + +def test_query_contracted_reserve_prices(client, country_code, start, end): + type_marketagreement_type = "A01" + result = client.query_contracted_reserve_prices( + country_code, start=start, end=end, type_marketagreement_type=type_marketagreement_type + ) + assert not result.empty + + +def test_query_contracted_reserve_amount(client, country_code, start, end): + type_marketagreement_type = "A01" + result = client.query_contracted_reserve_amount( + country_code, start=start, end=end, type_marketagreement_type=type_marketagreement_type + ) + assert not result.empty + + +def test_query_unavailability_transmission(client, country_code_from, country_code_to, start, end): + result = client.query_unavailability_transmission( + country_code_from, country_code_to, start=start, end=end + ) + assert not result.empty + + +def test_query_procured_balancing_capacity_process_type_not_allowed(client, country_code, start, end): + process_type = "A01" + with pytest.raises(ValueError): + client.query_procured_balancing_capacity( + country_code, start=start, end=end, process_type=process_type + ) + + +def test_query_procured_balancing_capacity(client, country_code, start, end): + process_type = "A47" + result = client.query_procured_balancing_capacity( + country_code, start=start, end=end, process_type=process_type + ) + assert not result.empty diff --git a/tests/test_raw.py b/tests/test_raw.py new file mode 100644 index 0000000..decc4c5 --- /dev/null +++ b/tests/test_raw.py @@ -0,0 +1,171 @@ +from itertools import product + +from bs4 import BeautifulSoup +from entsoe import EntsoeRawClient +from entsoe.exceptions import PaginationError +import pandas as pd +import pytest + +from settings import api_key + + +@pytest.fixture +def client(): + yield EntsoeRawClient(api_key=api_key) + + +def valid_xml(s: str) -> bool: + try: + BeautifulSoup(s, "html.parser") + return True + except Exception: + return False + + +@pytest.fixture +def start(): + return pd.Timestamp("20171201", tz="Europe/Brussels") + + +@pytest.fixture +def end(): + return pd.Timestamp("20180101", tz="Europe/Brussels") + + +@pytest.fixture +def country_code(): + return "BE" # Belgium + + +@pytest.fixture +def country_code_from(): + return "FR" # France + + +@pytest.fixture +def country_code_to(): + return "DE_LU" # Germany-Luxembourg + + +STARTS = [pd.Timestamp("20171201", tz="Europe/Brussels")] +ENDS = [pd.Timestamp("20180101", tz="Europe/Brussels")] +COUNTRY_CODES = ["BE"] # Belgium +COUNTRY_CODES_FROM = ["FR"] # France +COUNTRY_CODES_TO = ["DE_LU"] # Germany-Luxembourg + +BASIC_QUERIES = [ + "query_day_ahead_prices", + "query_net_position_dayahead", + "query_load", + "query_load_forecast", + "query_wind_and_solar_forecast", + "query_generation_forecast", + "query_generation", + "query_generation_per_plant", + "query_installed_generation_capacity", + "query_installed_generation_capacity_per_unit", +] + +CROSSBORDER_QUERIES = [ + "query_crossborder_flows", + "query_scheduled_exchanges", + "query_net_transfer_capacity_dayahead", + "query_net_transfer_capacity_weekahead", + "query_net_transfer_capacity_monthahead", + "query_net_transfer_capacity_yearahead", + "query_intraday_offered_capacity", +] + +# XML + +@pytest.mark.parametrize( + "country_code, start, end, query", + product(COUNTRY_CODES, STARTS, ENDS, BASIC_QUERIES), +) +def test_basic_queries(client, query, country_code, start, end): + result = getattr(client, query)(country_code, start, end) + assert isinstance(result, str) + assert valid_xml(result) + + +@pytest.mark.parametrize( + "country_code_from, country_code_to, start, end, query", + product(COUNTRY_CODES_FROM, COUNTRY_CODES_TO, STARTS, ENDS, CROSSBORDER_QUERIES), +) +def test_crossborder_queries( + client, query, country_code_from, country_code_to, start, end +): + result = getattr(client, query)(country_code_from, country_code_to, start, end) + assert isinstance(result, str) + assert valid_xml(result) + + +def test_query_contracted_reserve_prices(client, country_code, start, end): + type_marketagreement_type = "A01" + result = client.query_contracted_reserve_prices( + country_code, start, end, type_marketagreement_type + ) + assert isinstance(result, str) + assert valid_xml(result) + + +def test_query_contracted_reserve_amount(client, country_code, start, end): + type_marketagreement_type = "A01" + result = client.query_contracted_reserve_amount( + country_code, start, end, type_marketagreement_type + ) + assert isinstance(result, str) + assert valid_xml(result) + + +def test_query_procured_balancing_capacity_bytearray(client, country_code, start, end): + type_marketagreement_type = "A01" + process_type = "A47" + result = client.query_procured_balancing_capacity( + country_code, start, end, process_type, type_marketagreement_type + ) + assert isinstance(result, str) + assert valid_xml(result) + + +def test_query_procured_balancing_capacity_process_type_not_allowed(client): + type_marketagreement_type = "A01" + process_type = "A01" + with pytest.raises(ValueError): + client.query_procured_balancing_capacity( + country_code, start, end, process_type, type_marketagreement_type + ) + +# ZIP + +def test_query_imbalance_prices(client, country_code, start, end): + result = client.query_imbalance_prices(country_code, start, end) + assert isinstance(result, (bytes, bytearray)) + + +def test_query_unavailability_of_generation_units(client, country_code, start, end): + result = client.query_unavailability_of_generation_units(country_code, start, end,) + assert isinstance(result, (bytes, bytearray)) + + +def test_query_unavailability_of_production_units(client, country_code, start, end): + result = client.query_unavailability_of_production_units(country_code, start, end,) + assert isinstance(result, (bytes, bytearray)) + + +def test_query_unavailability_transmission( + client, country_code_from, country_code_to, start, end +): + result = client.query_unavailability_transmission( + country_code_from, country_code_to, start, end, + ) + assert isinstance(result, (bytes, bytearray)) + + +def test_query_withdrawn_unavailability_of_generation_units( + client, country_code, start, end +): + result = client.query_withdrawn_unavailability_of_generation_units( + country_code, start, end, + ) + assert isinstance(result, (bytes, bytearray))