From 55e16d0c96816d66d35ef4bacf4fa43d9250fc1a Mon Sep 17 00:00:00 2001 From: fleimgruber Date: Mon, 8 Aug 2022 12:32:18 +0200 Subject: [PATCH 1/6] test: draft of moving unit tests to canonical test directory --- tests/__init__.py | 0 tests/test_clients.py | 113 ++++++++++++++++++++++++++++++++++++++++++ tests/test_domains.py | 48 ++++++++++++++++++ 3 files changed, 161 insertions(+) create mode 100644 tests/__init__.py create mode 100644 tests/test_clients.py create mode 100644 tests/test_domains.py diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_clients.py b/tests/test_clients.py new file mode 100644 index 0000000..142449d --- /dev/null +++ b/tests/test_clients.py @@ -0,0 +1,113 @@ +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 new file mode 100644 index 0000000..6f91a0c --- /dev/null +++ b/tests/test_domains.py @@ -0,0 +1,48 @@ +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") From ba83e14419d8f585e2a2aadc590cbed86450969b Mon Sep 17 00:00:00 2001 From: fleimgruber Date: Mon, 8 Aug 2022 12:32:49 +0200 Subject: [PATCH 2/6] 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)) From 75b233f7c0996171b72bb986f3bf2a6e07a128b3 Mon Sep 17 00:00:00 2001 From: Fabio Leimgruber Date: Tue, 14 May 2024 19:33:59 +0200 Subject: [PATCH 3/6] feat: Use environment variable for API key --- tests/test_pandas.py | 8 ++++++-- tests/test_raw.py | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/tests/test_pandas.py b/tests/test_pandas.py index d42696b..4036508 100644 --- a/tests/test_pandas.py +++ b/tests/test_pandas.py @@ -1,15 +1,19 @@ from itertools import product +import os +from dotenv import load_dotenv from entsoe import EntsoePandasClient import pandas as pd import pytest -from settings import api_key +load_dotenv() + +API_KEY = os.getenv("API_KEY") @pytest.fixture def client(): - yield EntsoePandasClient(api_key=api_key) + yield EntsoePandasClient(api_key=API_KEY) @pytest.fixture diff --git a/tests/test_raw.py b/tests/test_raw.py index decc4c5..b4eff52 100644 --- a/tests/test_raw.py +++ b/tests/test_raw.py @@ -1,17 +1,21 @@ from itertools import product +import os from bs4 import BeautifulSoup +from dotenv import load_dotenv from entsoe import EntsoeRawClient from entsoe.exceptions import PaginationError import pandas as pd import pytest -from settings import api_key +load_dotenv() + +API_KEY = os.getenv("API_KEY") @pytest.fixture def client(): - yield EntsoeRawClient(api_key=api_key) + yield EntsoeRawClient(api_key=API_KEY) def valid_xml(s: str) -> bool: From e663678aeed17cce21b8698c9598bfd2cbd28a56 Mon Sep 17 00:00:00 2001 From: fleimgruber Date: Mon, 8 Aug 2022 11:24:58 +0200 Subject: [PATCH 4/6] fix: net position method renaming --- tests/test_pandas.py | 2 +- tests/test_raw.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_pandas.py b/tests/test_pandas.py index 4036508..cb8e646 100644 --- a/tests/test_pandas.py +++ b/tests/test_pandas.py @@ -49,7 +49,7 @@ def country_code_to(): BASIC_QUERIES_SERIES = [ "query_day_ahead_prices", - "query_net_position_dayahead", + "query_net_position", "query_load", "query_load_forecast", ] diff --git a/tests/test_raw.py b/tests/test_raw.py index b4eff52..2a64f52 100644 --- a/tests/test_raw.py +++ b/tests/test_raw.py @@ -59,7 +59,7 @@ def country_code_to(): BASIC_QUERIES = [ "query_day_ahead_prices", - "query_net_position_dayahead", + "query_net_position", "query_load", "query_load_forecast", "query_wind_and_solar_forecast", From 7204b3c45ac762c101696bef1f0ae82d7f90eeb9 Mon Sep 17 00:00:00 2001 From: Fabio Leimgruber Date: Tue, 14 May 2024 19:31:59 +0200 Subject: [PATCH 5/6] test: README changes on master --- tests/test_pandas.py | 20 +++++++++++++++----- tests/test_raw.py | 34 +++++++++++++++++++++++++--------- 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/tests/test_pandas.py b/tests/test_pandas.py index cb8e646..43f9073 100644 --- a/tests/test_pandas.py +++ b/tests/test_pandas.py @@ -50,11 +50,12 @@ def country_code_to(): BASIC_QUERIES_SERIES = [ "query_day_ahead_prices", "query_net_position", - "query_load", - "query_load_forecast", + "query_aggregate_water_reservoirs_and_hydro_storage", ] BASIC_QUERIES_DATAFRAME = [ + "query_load", + "query_load_forecast", "query_wind_and_solar_forecast", "query_generation_forecast", "query_generation", @@ -100,6 +101,15 @@ def test_crossborder_queries( result = getattr(client, query)(country_code_from, country_code_to, start=start, end=end) assert not result.empty + +def test_query_offered_capacity(client, country_code_from, country_code_to, start, end): + contract_marketagreement_type = "A01" + result = client.query_offered_capacity( + country_code_from, country_code_to, start, end, contract_marketagreement_type, implicit=True + ) + assert not result.empty + + # pandas.DataFrames @pytest.mark.parametrize( @@ -114,7 +124,7 @@ def test_basic_queries_dataframe(client, query, country_code, start, end): 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 + country_code, start=start, end=end, type_marketagreement_type=type_marketagreement_type, psr_type=None ) assert not result.empty @@ -122,7 +132,7 @@ def test_query_contracted_reserve_prices(client, country_code, start, end): 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 + country_code, start=start, end=end, type_marketagreement_type=type_marketagreement_type, psr_type=None ) assert not result.empty @@ -145,6 +155,6 @@ def test_query_procured_balancing_capacity_process_type_not_allowed(client, coun 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 + country_code, start=start, end=end, process_type=process_type, type_marketagreement_type=None ) assert not result.empty diff --git a/tests/test_raw.py b/tests/test_raw.py index 2a64f52..8300036 100644 --- a/tests/test_raw.py +++ b/tests/test_raw.py @@ -68,6 +68,7 @@ def country_code_to(): "query_generation_per_plant", "query_installed_generation_capacity", "query_installed_generation_capacity_per_unit", + "query_aggregate_water_reservoirs_and_hydro_storage", ] CROSSBORDER_QUERIES = [ @@ -77,7 +78,6 @@ def country_code_to(): "query_net_transfer_capacity_weekahead", "query_net_transfer_capacity_monthahead", "query_net_transfer_capacity_yearahead", - "query_intraday_offered_capacity", ] # XML @@ -104,10 +104,27 @@ def test_crossborder_queries( assert valid_xml(result) +def test_query_intraday_offered_capacity(client, country_code_from, country_code_to, start, end): + result = client.query_intraday_offered_capacity( + country_code_from, country_code_to, start, end, implicit=True + ) + assert isinstance(result, str) + assert valid_xml(result) + + +def test_query_offered_capacity(client, country_code_from, country_code_to, start, end): + contract_marketagreement_type = "A01" + result = client.query_offered_capacity( + country_code_from, country_code_to, start, end, contract_marketagreement_type, implicit=True + ) + 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 + country_code, start, end, type_marketagreement_type, psr_type=None ) assert isinstance(result, str) assert valid_xml(result) @@ -116,17 +133,16 @@ def test_query_contracted_reserve_prices(client, country_code, start, end): 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 + country_code, start, end, type_marketagreement_type, psr_type=None ) 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 + country_code, start, end, process_type, type_marketagreement_type=None ) assert isinstance(result, str) assert valid_xml(result) @@ -143,17 +159,17 @@ def test_query_procured_balancing_capacity_process_type_not_allowed(client): # ZIP def test_query_imbalance_prices(client, country_code, start, end): - result = client.query_imbalance_prices(country_code, start, end) + result = client.query_imbalance_prices(country_code, start, end, psr_type=None) 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,) + result = client.query_unavailability_of_generation_units(country_code, start, end, docstatus=None, periodstartupdate=None, periodendupdate=None) 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,) + result = client.query_unavailability_of_production_units(country_code, start, end, docstatus=None, periodstartupdate=None, periodendupdate=None) assert isinstance(result, (bytes, bytearray)) @@ -161,7 +177,7 @@ 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, + country_code_from, country_code_to, start, end, docstatus=None, periodstartupdate=None, periodendupdate=None ) assert isinstance(result, (bytes, bytearray)) From db66a091a4b7cbf55c33ee5dd6d16e90f3e516e2 Mon Sep 17 00:00:00 2001 From: Fabio Leimgruber Date: Tue, 14 May 2024 22:07:38 +0200 Subject: [PATCH 6/6] ci: First iteration of pytest --- .github/workflows/ci.yaml | 34 ++++++++++++++++++++++++++++++++++ requirements_dev.txt | 3 +++ tests/test_pandas.py | 2 +- 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/ci.yaml create mode 100644 requirements_dev.txt diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..3636711 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,34 @@ +name: ci + +on: + pull_request: + push: + branches: + - refactor_tests + +env: + API_KEY: ${{ secrets.ApiKey }} + +concurrency: + # Cancels pending runs when a PR gets updated. + group: ${{ github.head_ref || github.run_id }}-${{ github.actor }} + cancel-in-progress: true + +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ["3.9", "3.10", "3.11"] + steps: + - uses: actions/checkout@v4 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + python -m pip install -r requirements_dev.txt + - name: Run pytest + run: pytest diff --git a/requirements_dev.txt b/requirements_dev.txt new file mode 100644 index 0000000..449fb2c --- /dev/null +++ b/requirements_dev.txt @@ -0,0 +1,3 @@ +-r requirements.txt +pytest>=7.1.2 +python-dotenv>=0.20.0 \ No newline at end of file diff --git a/tests/test_pandas.py b/tests/test_pandas.py index 43f9073..239ad4b 100644 --- a/tests/test_pandas.py +++ b/tests/test_pandas.py @@ -105,7 +105,7 @@ def test_crossborder_queries( def test_query_offered_capacity(client, country_code_from, country_code_to, start, end): contract_marketagreement_type = "A01" result = client.query_offered_capacity( - country_code_from, country_code_to, start, end, contract_marketagreement_type, implicit=True + country_code_from, country_code_to, contract_marketagreement_type, start=start, end=end, implicit=True ) assert not result.empty