Преглед изворни кода

refactor excel dn write function

Toan Quach пре 1 година
родитељ
комит
65020a27ae

+ 5 - 7
taipy/core/_orchestrator/_orchestrator.py

@@ -96,7 +96,7 @@ class _Orchestrator(_AbstractOrchestrator):
             cls._check_and_execute_jobs_if_development_mode()
             cls._check_and_execute_jobs_if_development_mode()
         else:
         else:
             if wait:
             if wait:
-                cls._wait_until_job_finished(jobs, timeout=timeout)
+                cls._wait_until_job_finished(jobs, timeout=timeout or 0)
         return submission
         return submission
 
 
     @classmethod
     @classmethod
@@ -143,7 +143,7 @@ class _Orchestrator(_AbstractOrchestrator):
             cls._check_and_execute_jobs_if_development_mode()
             cls._check_and_execute_jobs_if_development_mode()
         else:
         else:
             if wait:
             if wait:
-                cls._wait_until_job_finished(job, timeout=timeout)
+                cls._wait_until_job_finished(job, timeout=timeout or 0)
         return submission
         return submission
 
 
     @classmethod
     @classmethod
@@ -185,12 +185,10 @@ class _Orchestrator(_AbstractOrchestrator):
             cls.jobs_to_run.put(job)
             cls.jobs_to_run.put(job)
 
 
     @classmethod
     @classmethod
-    def _wait_until_job_finished(cls, jobs: Union[List[Job], Job], timeout: Optional[Union[float, int]] = None):
+    def _wait_until_job_finished(cls, jobs: Union[List[Job], Job], timeout: float = 0):
         #  Note: this method should be prefixed by two underscores, but it has only one, so it can be mocked in tests.
         #  Note: this method should be prefixed by two underscores, but it has only one, so it can be mocked in tests.
         def __check_if_timeout(st, to):
         def __check_if_timeout(st, to):
-            if to:
-                return (datetime.now() - st).seconds < to
-            return True
+            return (datetime.now() - st).seconds < to
 
 
         start = datetime.now()
         start = datetime.now()
         jobs = list(jobs) if isinstance(jobs, Iterable) else [jobs]
         jobs = list(jobs) if isinstance(jobs, Iterable) else [jobs]
@@ -286,7 +284,7 @@ class _Orchestrator(_AbstractOrchestrator):
 
 
     @classmethod
     @classmethod
     def __remove_jobs_to_run(cls, jobs):
     def __remove_jobs_to_run(cls, jobs):
-        new_jobs_to_run: Queue = Queue()
+        new_jobs_to_run = Queue()
         while not cls.jobs_to_run.empty():
         while not cls.jobs_to_run.empty():
             current_job = cls.jobs_to_run.get()
             current_job = cls.jobs_to_run.get()
             if current_job not in jobs:
             if current_job not in jobs:

+ 16 - 0
taipy/core/data/_abstract_tabular.py

@@ -9,6 +9,12 @@
 # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 # an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 # specific language governing permissions and limitations under the License.
 # specific language governing permissions and limitations under the License.
 
 
+from dataclasses import asdict, is_dataclass
+from typing import Any, Union
+
+import numpy as np
+import pandas as pd
+
 from ..exceptions.exceptions import InvalidExposedType
 from ..exceptions.exceptions import InvalidExposedType
 
 
 
 
@@ -22,6 +28,16 @@ class _AbstractTabularDataNode(object):
     _EXPOSED_TYPE_MODIN = "modin"  # Deprecated in favor of pandas since 3.1.0
     _EXPOSED_TYPE_MODIN = "modin"  # Deprecated in favor of pandas since 3.1.0
     __VALID_STRING_EXPOSED_TYPES = [_EXPOSED_TYPE_PANDAS, _EXPOSED_TYPE_NUMPY]
     __VALID_STRING_EXPOSED_TYPES = [_EXPOSED_TYPE_PANDAS, _EXPOSED_TYPE_NUMPY]
 
 
+    def _convert_data_to_dataframe(self, exposed_type: Any, data: Any) -> Union[pd.DataFrame, pd.Series]:
+        if exposed_type == self._EXPOSED_TYPE_PANDAS and isinstance(data, (pd.DataFrame, pd.Series)):
+            return data
+        elif exposed_type == self._EXPOSED_TYPE_NUMPY and isinstance(data, np.ndarray):
+            return pd.DataFrame(data)
+        elif isinstance(data, list) and not isinstance(exposed_type, str):
+            if all(is_dataclass(row) for row in data):
+                return pd.DataFrame.from_records([asdict(row) for row in data])
+        return pd.DataFrame(data)
+
     @staticmethod
     @staticmethod
     def _check_exposed_type(exposed_type):
     def _check_exposed_type(exposed_type):
         valid_string_exposed_types = _AbstractTabularDataNode.__VALID_STRING_EXPOSED_TYPES
         valid_string_exposed_types = _AbstractTabularDataNode.__VALID_STRING_EXPOSED_TYPES

+ 4 - 19
taipy/core/data/csv.py

@@ -11,7 +11,6 @@
 
 
 import csv
 import csv
 import os
 import os
-from dataclasses import asdict, is_dataclass
 from datetime import datetime, timedelta
 from datetime import datetime, timedelta
 from os.path import isfile
 from os.path import isfile
 from typing import Any, Dict, List, Optional, Set
 from typing import Any, Dict, List, Optional, Set
@@ -185,9 +184,7 @@ class CSVDataNode(DataNode, _AbstractFileDataNode, _AbstractTabularDataNode):
                 for line in reader:
                 for line in reader:
                     res.append(custom_class(**line))
                     res.append(custom_class(**line))
             else:
             else:
-                reader = csv.reader(
-                    csvFile,
-                )
+                reader = csv.reader(csvFile)
                 for line in reader:
                 for line in reader:
                     res.append(custom_class(*line))
                     res.append(custom_class(*line))
             return res
             return res
@@ -220,26 +217,14 @@ class CSVDataNode(DataNode, _AbstractFileDataNode, _AbstractTabularDataNode):
                 self._path, mode="a", index=False, encoding=self.properties[self.__ENCODING_KEY], header=False
                 self._path, mode="a", index=False, encoding=self.properties[self.__ENCODING_KEY], header=False
             )
             )
 
 
-    def __convert_data_to_dataframe(self, data: Any):
-        exposed_type = self.properties[self._EXPOSED_TYPE_PROPERTY]
-        if exposed_type == self._EXPOSED_TYPE_PANDAS and isinstance(data, (pd.DataFrame, pd.Series)):
-            return data
-        elif exposed_type == self._EXPOSED_TYPE_NUMPY and isinstance(data, np.ndarray):
-            return pd.DataFrame(data)
-        elif isinstance(data, list) and not isinstance(exposed_type, str):
-            if all(is_dataclass(row) for row in data):
-                return pd.DataFrame.from_records([asdict(row) for row in data])
-            # return pd.DataFrame.from_records([row.to_dict() for row in data])
-        else:
-            return pd.DataFrame(data)
-
     def _write(self, data: Any):
     def _write(self, data: Any):
+        exposed_type = self.properties[self._EXPOSED_TYPE_PROPERTY]
         if self.properties[self.__HAS_HEADER_PROPERTY]:
         if self.properties[self.__HAS_HEADER_PROPERTY]:
-            self.__convert_data_to_dataframe(data).to_csv(
+            self._convert_data_to_dataframe(exposed_type, data).to_csv(
                 self._path, index=False, encoding=self.properties[self.__ENCODING_KEY]
                 self._path, index=False, encoding=self.properties[self.__ENCODING_KEY]
             )
             )
         else:
         else:
-            self.__convert_data_to_dataframe(data).to_csv(
+            self._convert_data_to_dataframe(exposed_type, data).to_csv(
                 self._path, index=False, encoding=self.properties[self.__ENCODING_KEY], header=None
                 self._path, index=False, encoding=self.properties[self.__ENCODING_KEY], header=None
             )
             )
 
 

+ 6 - 22
taipy/core/data/excel.py

@@ -263,7 +263,7 @@ class ExcelDataNode(DataNode, _AbstractFileDataNode, _AbstractTabularDataNode):
         return pd.read_excel(self._path, sheet_name=sheet_names, **kwargs)
         return pd.read_excel(self._path, sheet_name=sheet_names, **kwargs)
 
 
     def __get_sheet_names_and_header(self, sheet_names):
     def __get_sheet_names_and_header(self, sheet_names):
-        kwargs: Dict[str, Any] = {}
+        kwargs = {}
         if sheet_names is None:
         if sheet_names is None:
             sheet_names = self.properties[self.__SHEET_NAME_PROPERTY]
             sheet_names = self.properties[self.__SHEET_NAME_PROPERTY]
         if not self.properties[self.__HAS_HEADER_PROPERTY]:
         if not self.properties[self.__HAS_HEADER_PROPERTY]:
@@ -331,10 +331,7 @@ class ExcelDataNode(DataNode, _AbstractFileDataNode, _AbstractTabularDataNode):
         with pd.ExcelWriter(self._path) as writer:
         with pd.ExcelWriter(self._path) as writer:
             # Each key stands for a sheet name
             # Each key stands for a sheet name
             for key in data.keys():
             for key in data.keys():
-                if isinstance(data[key], np.ndarray):
-                    df = pd.DataFrame(data[key])
-                else:
-                    df = data[key]
+                df = self._convert_data_to_dataframe(self.properties[self._EXPOSED_TYPE_PROPERTY], data[key])
 
 
                 if columns:
                 if columns:
                     data[key].columns = columns
                     data[key].columns = columns
@@ -342,24 +339,11 @@ class ExcelDataNode(DataNode, _AbstractFileDataNode, _AbstractTabularDataNode):
                 df.to_excel(writer, key, index=False)
                 df.to_excel(writer, key, index=False)
 
 
     def _write(self, data: Any):
     def _write(self, data: Any):
-        # TODO:
-        # if dict -> multi sheet
-        # 1 pandas as child
-        # 2 numpy as child
-        # 3 custom as child
-
-        # if pandas
-
-        # if numpy
-
-        # if custom exposed type
-
-        if isinstance(data, Dict) and all(isinstance(x, (pd.DataFrame, np.ndarray)) for x in data.values()):
-            self.__write_excel_with_multiple_sheets(data)
-        elif isinstance(data, pd.DataFrame):
-            self.__write_excel_with_single_sheet(data.to_excel, self._path, index=False)
+        if isinstance(data, Dict):
+            return self.__write_excel_with_multiple_sheets(data)
         else:
         else:
-            self.__write_excel_with_single_sheet(pd.DataFrame(data).to_excel, self._path, index=False)
+            data = self._convert_data_to_dataframe(self.properties[self._EXPOSED_TYPE_PROPERTY], data)
+            self.__write_excel_with_single_sheet(data.to_excel, self._path, index=False)
 
 
     def write_with_column_names(self, data: Any, columns: List[str] = None, job_id: Optional[JobId] = None):
     def write_with_column_names(self, data: Any, columns: List[str] = None, job_id: Optional[JobId] = None):
         """Write a set of columns.
         """Write a set of columns.

+ 7 - 4
taipy/core/data/parquet.py

@@ -244,10 +244,13 @@ class ParquetDataNode(DataNode, _AbstractFileDataNode, _AbstractTabularDataNode)
         }
         }
         kwargs.update(self.properties[self.__WRITE_KWARGS_PROPERTY])
         kwargs.update(self.properties[self.__WRITE_KWARGS_PROPERTY])
         kwargs.update(write_kwargs)
         kwargs.update(write_kwargs)
-        if isinstance(data, pd.DataFrame):
-            data.to_parquet(self._path, **kwargs)
-        else:
-            pd.DataFrame(data).to_parquet(self._path, **kwargs)
+
+        # TODO: test this new code
+        data = self._convert_data_to_dataframe(self.properties[self._EXPOSED_TYPE_PROPERTY], data)
+        if isinstance(data, pd.Series):
+            data = pd.DataFrame(data)
+        data.to_parquet(self._path, **kwargs)
+
         self.track_edit(timestamp=datetime.now(), job_id=job_id)
         self.track_edit(timestamp=datetime.now(), job_id=job_id)
 
 
     def read_with_kwargs(self, **read_kwargs):
     def read_with_kwargs(self, **read_kwargs):

+ 15 - 24
tests/core/data/test_read_csv_data_node.py

@@ -21,7 +21,7 @@ from taipy.config.common.scope import Scope
 from taipy.core.data.csv import CSVDataNode
 from taipy.core.data.csv import CSVDataNode
 from taipy.core.exceptions.exceptions import NoData
 from taipy.core.exceptions.exceptions import NoData
 
 
-DATA_SAMPLE_PATH = "data_sample/example.csv"
+csv_file_path = os.path.join(pathlib.Path(__file__).parent.resolve(), "data_sample/example.csv")
 
 
 
 
 @dataclasses.dataclass
 @dataclasses.dataclass
@@ -39,33 +39,28 @@ def test_raise_no_data_with_header():
 
 
 
 
 def test_read_with_header_pandas():
 def test_read_with_header_pandas():
-    path = os.path.join(pathlib.Path(__file__).parent.resolve(), DATA_SAMPLE_PATH)
-
-    csv_data_node_as_pandas = CSVDataNode("bar", Scope.SCENARIO, properties={"path": path})
+    csv_data_node_as_pandas = CSVDataNode("bar", Scope.SCENARIO, properties={"path": csv_file_path})
     data_pandas = csv_data_node_as_pandas.read()
     data_pandas = csv_data_node_as_pandas.read()
     assert isinstance(data_pandas, pd.DataFrame)
     assert isinstance(data_pandas, pd.DataFrame)
     assert len(data_pandas) == 10
     assert len(data_pandas) == 10
-    assert np.array_equal(data_pandas.to_numpy(), pd.read_csv(path).to_numpy())
+    assert pd.DataFrame.equals(data_pandas, pd.read_csv(csv_file_path))
 
 
 
 
 def test_read_with_header_numpy():
 def test_read_with_header_numpy():
-    path = os.path.join(pathlib.Path(__file__).parent.resolve(), DATA_SAMPLE_PATH)
-
     csv_data_node_as_numpy = CSVDataNode(
     csv_data_node_as_numpy = CSVDataNode(
-        "bar", Scope.SCENARIO, properties={"path": path, "has_header": True, "exposed_type": "numpy"}
+        "bar", Scope.SCENARIO, properties={"path": csv_file_path, "has_header": True, "exposed_type": "numpy"}
     )
     )
     data_numpy = csv_data_node_as_numpy.read()
     data_numpy = csv_data_node_as_numpy.read()
     assert isinstance(data_numpy, np.ndarray)
     assert isinstance(data_numpy, np.ndarray)
     assert len(data_numpy) == 10
     assert len(data_numpy) == 10
-    assert np.array_equal(data_numpy, pd.read_csv(path).to_numpy())
+    assert np.array_equal(data_numpy, pd.read_csv(csv_file_path).to_numpy())
 
 
 
 
 def test_read_with_header_custom_exposed_type():
 def test_read_with_header_custom_exposed_type():
-    path = os.path.join(pathlib.Path(__file__).parent.resolve(), DATA_SAMPLE_PATH)
-    data_pandas = pd.read_csv(path)
+    data_pandas = pd.read_csv(csv_file_path)
 
 
     csv_data_node_as_custom_object = CSVDataNode(
     csv_data_node_as_custom_object = CSVDataNode(
-        "bar", Scope.SCENARIO, properties={"path": path, "exposed_type": MyCustomObject}
+        "bar", Scope.SCENARIO, properties={"path": csv_file_path, "exposed_type": MyCustomObject}
     )
     )
     data_custom = csv_data_node_as_custom_object.read()
     data_custom = csv_data_node_as_custom_object.read()
     assert isinstance(data_custom, list)
     assert isinstance(data_custom, list)
@@ -86,38 +81,34 @@ def test_raise_no_data_without_header():
 
 
 
 
 def test_read_without_header_pandas():
 def test_read_without_header_pandas():
-    path = os.path.join(pathlib.Path(__file__).parent.resolve(), DATA_SAMPLE_PATH)
-
-    csv_data_node_as_pandas = CSVDataNode("bar", Scope.SCENARIO, properties={"path": path, "has_header": False})
+    csv_data_node_as_pandas = CSVDataNode(
+        "bar", Scope.SCENARIO, properties={"path": csv_file_path, "has_header": False}
+    )
     data_pandas = csv_data_node_as_pandas.read()
     data_pandas = csv_data_node_as_pandas.read()
     assert isinstance(data_pandas, pd.DataFrame)
     assert isinstance(data_pandas, pd.DataFrame)
     assert len(data_pandas) == 11
     assert len(data_pandas) == 11
-    assert np.array_equal(data_pandas.to_numpy(), pd.read_csv(path, header=None).to_numpy())
+    assert pd.DataFrame.equals(data_pandas, pd.read_csv(csv_file_path, header=None))
 
 
 
 
 def test_read_without_header_numpy():
 def test_read_without_header_numpy():
-    path = os.path.join(pathlib.Path(__file__).parent.resolve(), DATA_SAMPLE_PATH)
-
     csv_data_node_as_numpy = CSVDataNode(
     csv_data_node_as_numpy = CSVDataNode(
-        "qux", Scope.SCENARIO, properties={"path": path, "has_header": False, "exposed_type": "numpy"}
+        "qux", Scope.SCENARIO, properties={"path": csv_file_path, "has_header": False, "exposed_type": "numpy"}
     )
     )
     data_numpy = csv_data_node_as_numpy.read()
     data_numpy = csv_data_node_as_numpy.read()
     assert isinstance(data_numpy, np.ndarray)
     assert isinstance(data_numpy, np.ndarray)
     assert len(data_numpy) == 11
     assert len(data_numpy) == 11
-    assert np.array_equal(data_numpy, pd.read_csv(path, header=None).to_numpy())
+    assert np.array_equal(data_numpy, pd.read_csv(csv_file_path, header=None).to_numpy())
 
 
 
 
 def test_read_without_header_custom_exposed_type():
 def test_read_without_header_custom_exposed_type():
-    path = os.path.join(pathlib.Path(__file__).parent.resolve(), DATA_SAMPLE_PATH)
-
     csv_data_node_as_custom_object = CSVDataNode(
     csv_data_node_as_custom_object = CSVDataNode(
-        "quux", Scope.SCENARIO, properties={"path": path, "has_header": False, "exposed_type": MyCustomObject}
+        "quux", Scope.SCENARIO, properties={"path": csv_file_path, "has_header": False, "exposed_type": MyCustomObject}
     )
     )
     data_custom = csv_data_node_as_custom_object.read()
     data_custom = csv_data_node_as_custom_object.read()
     assert isinstance(data_custom, list)
     assert isinstance(data_custom, list)
     assert len(data_custom) == 11
     assert len(data_custom) == 11
 
 
-    data_pandas = pd.read_csv(path, header=None)
+    data_pandas = pd.read_csv(csv_file_path, header=None)
     for (_, row_pandas), row_custom in zip(data_pandas.iterrows(), data_custom):
     for (_, row_pandas), row_custom in zip(data_pandas.iterrows(), data_custom):
         assert isinstance(row_custom, MyCustomObject)
         assert isinstance(row_custom, MyCustomObject)
         assert row_pandas[0] == row_custom.id
         assert row_pandas[0] == row_custom.id

+ 217 - 140
tests/core/data/test_read_excel_data_node.py

@@ -55,59 +55,126 @@ class MyCustomObject2:
         self.text = text
         self.text = text
 
 
 
 
-def test_read_with_header():
+excel_file_path = os.path.join(pathlib.Path(__file__).parent.resolve(), "data_sample/example.xlsx")
+sheet_names = ["Sheet1", "Sheet2"]
+custom_class_dict = {"Sheet1": MyCustomObject1, "Sheet2": MyCustomObject2}
+
+
+def test_raise_no_data_with_header():
     with pytest.raises(NoData):
     with pytest.raises(NoData):
         not_existing_excel = ExcelDataNode("foo", Scope.SCENARIO, properties={"path": "WRONG.xlsx"})
         not_existing_excel = ExcelDataNode("foo", Scope.SCENARIO, properties={"path": "WRONG.xlsx"})
         assert not_existing_excel.read() is None
         assert not_existing_excel.read() is None
         not_existing_excel.read_or_raise()
         not_existing_excel.read_or_raise()
 
 
+
+def test_read_empty_excel_with_header():
     empty_excel_path = os.path.join(pathlib.Path(__file__).parent.resolve(), "data_sample/empty.xlsx")
     empty_excel_path = os.path.join(pathlib.Path(__file__).parent.resolve(), "data_sample/empty.xlsx")
     empty_excel = ExcelDataNode(
     empty_excel = ExcelDataNode(
         "foo",
         "foo",
         Scope.SCENARIO,
         Scope.SCENARIO,
-        properties={"path": empty_excel_path, "exposed_type": MyCustomObject, "has_header": True},
+        properties={"path": empty_excel_path, "exposed_type": MyCustomObject},
     )
     )
     assert len(empty_excel.read()) == 0
     assert len(empty_excel.read()) == 0
 
 
-    path = os.path.join(pathlib.Path(__file__).parent.resolve(), "data_sample/example.xlsx")
 
 
-    # Create ExcelDataNode without exposed_type (Default is pandas.DataFrame)
-    excel_data_node_as_pandas = ExcelDataNode("bar", Scope.SCENARIO, properties={"path": path, "sheet_name": "Sheet1"})
+def test_raise_no_data_without_header():
+    with pytest.raises(NoData):
+        not_existing_excel = ExcelDataNode(
+            "foo", Scope.SCENARIO, properties={"path": "WRONG.xlsx", "has_header": False}
+        )
+        assert not_existing_excel.read() is None
+        not_existing_excel.read_or_raise()
+
+
+def test_read_empty_excel_without_header():
+    empty_excel_path = os.path.join(pathlib.Path(__file__).parent.resolve(), "data_sample/empty.xlsx")
+    empty_excel = ExcelDataNode(
+        "foo",
+        Scope.SCENARIO,
+        properties={"path": empty_excel_path, "exposed_type": MyCustomObject, "has_header": False},
+    )
+    assert len(empty_excel.read()) == 0
+
+
+def test_read_multi_sheet_with_header_no_data():
+    not_existing_excel = ExcelDataNode(
+        "foo",
+        Scope.SCENARIO,
+        properties={"path": "WRONG.xlsx", "sheet_name": ["sheet_name_1", "sheet_name_2"]},
+    )
+    with pytest.raises(NoData):
+        assert not_existing_excel.read() is None
+        not_existing_excel.read_or_raise()
+
+
+def test_read_multi_sheet_without_header_no_data():
+    not_existing_excel = ExcelDataNode(
+        "foo",
+        Scope.SCENARIO,
+        properties={"path": "WRONG.xlsx", "has_header": False, "sheet_name": ["sheet_name_1", "sheet_name_2"]},
+    )
+    with pytest.raises(NoData):
+        assert not_existing_excel.read() is None
+        not_existing_excel.read_or_raise()
+
+
+########################## SINGLE SHEET ##########################
+
+
+def test_read_single_sheet_with_header_no_existing_sheet():
+    non_existing_sheet_name_custom = ExcelDataNode(
+        "bar",
+        Scope.SCENARIO,
+        properties={"path": excel_file_path, "sheet_name": "abc", "exposed_type": MyCustomObject},
+    )
+    with pytest.raises(NonExistingExcelSheet):
+        non_existing_sheet_name_custom.read()
+
+
+def test_read_single_sheet_without_header_no_existing_sheet():
+    non_existing_sheet_name_custom = ExcelDataNode(
+        "bar",
+        Scope.SCENARIO,
+        properties={"path": excel_file_path, "has_header": False, "sheet_name": "abc", "exposed_type": MyCustomObject},
+    )
+    with pytest.raises(NonExistingExcelSheet):
+        non_existing_sheet_name_custom.read()
+
+
+def test_read_with_header_pandas():
+    excel_data_node_as_pandas = ExcelDataNode(
+        "bar", Scope.SCENARIO, properties={"path": excel_file_path, "sheet_name": "Sheet1"}
+    )
 
 
     data_pandas = excel_data_node_as_pandas.read()
     data_pandas = excel_data_node_as_pandas.read()
     assert isinstance(data_pandas, pd.DataFrame)
     assert isinstance(data_pandas, pd.DataFrame)
     assert len(data_pandas) == 5
     assert len(data_pandas) == 5
-    assert np.array_equal(data_pandas.to_numpy(), pd.read_excel(path).to_numpy())
+    assert pd.DataFrame.equals(data_pandas, pd.read_excel(excel_file_path))
+
 
 
-    # Create ExcelDataNode with numpy exposed_type
+def test_read_with_header_numpy():
     excel_data_node_as_numpy = ExcelDataNode(
     excel_data_node_as_numpy = ExcelDataNode(
-        "bar", Scope.SCENARIO, properties={"path": path, "exposed_type": "numpy", "sheet_name": "Sheet1"}
+        "bar", Scope.SCENARIO, properties={"path": excel_file_path, "exposed_type": "numpy", "sheet_name": "Sheet1"}
     )
     )
 
 
     data_numpy = excel_data_node_as_numpy.read()
     data_numpy = excel_data_node_as_numpy.read()
     assert isinstance(data_numpy, np.ndarray)
     assert isinstance(data_numpy, np.ndarray)
     assert len(data_numpy) == 5
     assert len(data_numpy) == 5
-    assert np.array_equal(data_numpy, pd.read_excel(path).to_numpy())
+    assert np.array_equal(data_numpy, pd.read_excel(excel_file_path).to_numpy())
 
 
-    # Create the same ExcelDataNode but with custom exposed_type
-    non_existing_sheet_name_custom = ExcelDataNode(
-        "bar",
-        Scope.SCENARIO,
-        properties={"path": path, "sheet_name": "abc", "exposed_type": MyCustomObject},
-    )
-    with pytest.raises(NonExistingExcelSheet):
-        non_existing_sheet_name_custom.read()
 
 
+def test_read_with_header_custom_exposed_type():
     excel_data_node_as_custom_object = ExcelDataNode(
     excel_data_node_as_custom_object = ExcelDataNode(
         "bar",
         "bar",
         Scope.SCENARIO,
         Scope.SCENARIO,
-        properties={"path": path, "exposed_type": MyCustomObject, "sheet_name": "Sheet1"},
+        properties={"path": excel_file_path, "exposed_type": MyCustomObject, "sheet_name": "Sheet1"},
     )
     )
 
 
     data_custom = excel_data_node_as_custom_object.read()
     data_custom = excel_data_node_as_custom_object.read()
     assert isinstance(data_custom, list)
     assert isinstance(data_custom, list)
     assert len(data_custom) == 5
     assert len(data_custom) == 5
 
 
+    data_pandas = pd.read_excel(excel_file_path)
     for (_, row_pandas), row_custom in zip(data_pandas.iterrows(), data_custom):
     for (_, row_pandas), row_custom in zip(data_pandas.iterrows(), data_custom):
         assert isinstance(row_custom, MyCustomObject)
         assert isinstance(row_custom, MyCustomObject)
         assert row_pandas["id"] == row_custom.id
         assert row_pandas["id"] == row_custom.id
@@ -115,49 +182,35 @@ def test_read_with_header():
         assert row_pandas["text"] == row_custom.text
         assert row_pandas["text"] == row_custom.text
 
 
 
 
-def test_read_without_header():
-    not_existing_excel = ExcelDataNode("foo", Scope.SCENARIO, properties={"path": "WRONG.xlsx", "has_header": False})
-    with pytest.raises(NoData):
-        assert not_existing_excel.read() is None
-        not_existing_excel.read_or_raise()
-
-    path = os.path.join(pathlib.Path(__file__).parent.resolve(), "data_sample/example.xlsx")
-
-    # Create ExcelDataNode without exposed_type (Default is pandas.DataFrame)
+def test_read_without_header_pandas():
     excel_data_node_as_pandas = ExcelDataNode(
     excel_data_node_as_pandas = ExcelDataNode(
-        "bar", Scope.SCENARIO, properties={"path": path, "has_header": False, "sheet_name": "Sheet1"}
+        "bar", Scope.SCENARIO, properties={"path": excel_file_path, "has_header": False, "sheet_name": "Sheet1"}
     )
     )
     data_pandas = excel_data_node_as_pandas.read()
     data_pandas = excel_data_node_as_pandas.read()
     assert isinstance(data_pandas, pd.DataFrame)
     assert isinstance(data_pandas, pd.DataFrame)
     assert len(data_pandas) == 6
     assert len(data_pandas) == 6
-    assert np.array_equal(data_pandas.to_numpy(), pd.read_excel(path, header=None).to_numpy())
+    assert pd.DataFrame.equals(data_pandas, pd.read_excel(excel_file_path, header=None))
+
 
 
-    # Create ExcelDataNode with numpy exposed_type
+def test_read_without_header_numpy():
     excel_data_node_as_numpy = ExcelDataNode(
     excel_data_node_as_numpy = ExcelDataNode(
         "bar",
         "bar",
         Scope.SCENARIO,
         Scope.SCENARIO,
-        properties={"path": path, "has_header": False, "exposed_type": "numpy", "sheet_name": "Sheet1"},
+        properties={"path": excel_file_path, "has_header": False, "exposed_type": "numpy", "sheet_name": "Sheet1"},
     )
     )
 
 
     data_numpy = excel_data_node_as_numpy.read()
     data_numpy = excel_data_node_as_numpy.read()
     assert isinstance(data_numpy, np.ndarray)
     assert isinstance(data_numpy, np.ndarray)
     assert len(data_numpy) == 6
     assert len(data_numpy) == 6
-    assert np.array_equal(data_numpy, pd.read_excel(path, header=None).to_numpy())
+    assert np.array_equal(data_numpy, pd.read_excel(excel_file_path, header=None).to_numpy())
 
 
-    # Create the same ExcelDataNode but with custom exposed_type
-    non_existing_sheet_name_custom = ExcelDataNode(
-        "bar",
-        Scope.SCENARIO,
-        properties={"path": path, "has_header": False, "sheet_name": "abc", "exposed_type": MyCustomObject},
-    )
-    with pytest.raises(NonExistingExcelSheet):
-        non_existing_sheet_name_custom.read()
 
 
+def test_read_without_header_exposed_custom_type():
     excel_data_node_as_custom_object = ExcelDataNode(
     excel_data_node_as_custom_object = ExcelDataNode(
         "bar",
         "bar",
         Scope.SCENARIO,
         Scope.SCENARIO,
         properties={
         properties={
-            "path": path,
+            "path": excel_file_path,
             "has_header": False,
             "has_header": False,
             "exposed_type": MyCustomObject,
             "exposed_type": MyCustomObject,
             "sheet_name": "Sheet1",
             "sheet_name": "Sheet1",
@@ -168,6 +221,7 @@ def test_read_without_header():
     assert isinstance(data_custom, list)
     assert isinstance(data_custom, list)
     assert len(data_custom) == 6
     assert len(data_custom) == 6
 
 
+    data_pandas = pd.read_excel(excel_file_path, header=None)
     for (_, row_pandas), row_custom in zip(data_pandas.iterrows(), data_custom):
     for (_, row_pandas), row_custom in zip(data_pandas.iterrows(), data_custom):
         assert isinstance(row_custom, MyCustomObject)
         assert isinstance(row_custom, MyCustomObject)
         assert row_pandas[0] == row_custom.id
         assert row_pandas[0] == row_custom.id
@@ -175,22 +229,71 @@ def test_read_without_header():
         assert row_pandas[2] == row_custom.text
         assert row_pandas[2] == row_custom.text
 
 
 
 
-def test_read_multi_sheet_with_header():
-    not_existing_excel = ExcelDataNode(
-        "foo",
+########################## MULTI SHEET ##########################
+
+
+def test_read_multi_sheet_with_header_no_existing_sheet():
+    non_existing_sheet_name_custom = ExcelDataNode(
+        "bar",
         Scope.SCENARIO,
         Scope.SCENARIO,
-        properties={"path": "WRONG.xlsx", "sheet_name": ["sheet_name_1", "sheet_name_2"]},
+        properties={
+            "path": excel_file_path,
+            "sheet_name": ["Sheet1", "xyz"],
+            "exposed_type": MyCustomObject1,
+        },
     )
     )
-    with pytest.raises(NoData):
-        assert not_existing_excel.read() is None
-        not_existing_excel.read_or_raise()
+    with pytest.raises(NonExistingExcelSheet):
+        non_existing_sheet_name_custom.read()
+
+
+def test_read_multi_sheet_without_header_no_existing_sheet():
+    non_existing_sheet_name_custom = ExcelDataNode(
+        "bar",
+        Scope.SCENARIO,
+        properties={
+            "path": excel_file_path,
+            "has_header": False,
+            "sheet_name": ["Sheet1", "xyz"],
+            "exposed_type": MyCustomObject1,
+        },
+    )
+    with pytest.raises(NonExistingExcelSheet):
+        non_existing_sheet_name_custom.read()
 
 
-    path = os.path.join(pathlib.Path(__file__).parent.resolve(), "data_sample/example.xlsx")
-    sheet_names = ["Sheet1", "Sheet2"]
 
 
-    # Create ExcelDataNode without exposed_type (Default is pandas.DataFrame)
+def test_raise_exposed_type_length_mismatch_with_header():
+    with pytest.raises(ExposedTypeLengthMismatch):
+        dn = ExcelDataNode(
+            "bar",
+            Scope.SCENARIO,
+            properties={
+                "path": excel_file_path,
+                "sheet_name": ["Sheet1"],
+                "exposed_type": [MyCustomObject1, MyCustomObject2],
+            },
+        )
+        dn.read()
+
+
+def test_raise_exposed_type_length_mismatch_without_header():
+    with pytest.raises(ExposedTypeLengthMismatch):
+        dn = ExcelDataNode(
+            "bar",
+            Scope.SCENARIO,
+            properties={
+                "path": excel_file_path,
+                "sheet_name": ["Sheet1"],
+                "exposed_type": [MyCustomObject1, MyCustomObject2],
+                "has_header": False,
+            },
+        )
+        dn.read()
+
+
+def test_read_multi_sheet_with_header_pandas():
+    # With sheet name
     excel_data_node_as_pandas = ExcelDataNode(
     excel_data_node_as_pandas = ExcelDataNode(
-        "bar", Scope.SCENARIO, properties={"path": path, "sheet_name": sheet_names}
+        "bar", Scope.SCENARIO, properties={"path": excel_file_path, "sheet_name": sheet_names}
     )
     )
 
 
     data_pandas = excel_data_node_as_pandas.read()
     data_pandas = excel_data_node_as_pandas.read()
@@ -202,9 +305,10 @@ def test_read_multi_sheet_with_header():
     )
     )
     assert list(data_pandas.keys()) == sheet_names
     assert list(data_pandas.keys()) == sheet_names
     for sheet_name in sheet_names:
     for sheet_name in sheet_names:
-        assert data_pandas[sheet_name].equals(pd.read_excel(path, sheet_name=sheet_name))
+        assert pd.DataFrame.equals(data_pandas[sheet_name], pd.read_excel(excel_file_path, sheet_name=sheet_name))
 
 
-    excel_data_node_as_pandas_no_sheet_name = ExcelDataNode("bar", Scope.SCENARIO, properties={"path": path})
+    # Without sheet name
+    excel_data_node_as_pandas_no_sheet_name = ExcelDataNode("bar", Scope.SCENARIO, properties={"path": excel_file_path})
 
 
     data_pandas_no_sheet_name = excel_data_node_as_pandas_no_sheet_name.read()
     data_pandas_no_sheet_name = excel_data_node_as_pandas_no_sheet_name.read()
     assert isinstance(data_pandas_no_sheet_name, Dict)
     assert isinstance(data_pandas_no_sheet_name, Dict)
@@ -212,11 +316,15 @@ def test_read_multi_sheet_with_header():
         assert isinstance(data_pandas_no_sheet_name[key], pd.DataFrame)
         assert isinstance(data_pandas_no_sheet_name[key], pd.DataFrame)
         assert data_pandas[key].equals(data_pandas_no_sheet_name[key])
         assert data_pandas[key].equals(data_pandas_no_sheet_name[key])
 
 
-    # Create ExcelDataNode with numpy exposed_type
+
+def test_read_multi_sheet_with_header_numpy():
+    data_pandas = pd.read_excel(excel_file_path, sheet_name=sheet_names)
+
+    # With sheet name
     excel_data_node_as_numpy = ExcelDataNode(
     excel_data_node_as_numpy = ExcelDataNode(
         "bar",
         "bar",
         Scope.SCENARIO,
         Scope.SCENARIO,
-        properties={"path": path, "sheet_name": sheet_names, "exposed_type": "numpy"},
+        properties={"path": excel_file_path, "sheet_name": sheet_names, "exposed_type": "numpy"},
     )
     )
 
 
     data_numpy = excel_data_node_as_numpy.read()
     data_numpy = excel_data_node_as_numpy.read()
@@ -228,12 +336,13 @@ def test_read_multi_sheet_with_header():
     )
     )
     assert list(data_numpy.keys()) == sheet_names
     assert list(data_numpy.keys()) == sheet_names
     for sheet_name in sheet_names:
     for sheet_name in sheet_names:
-        assert np.array_equal(data_pandas[sheet_name], pd.read_excel(path, sheet_name=sheet_name).to_numpy())
+        assert np.array_equal(data_pandas[sheet_name], pd.read_excel(excel_file_path, sheet_name=sheet_name).to_numpy())
 
 
+    # Without sheet name
     excel_data_node_as_numpy_no_sheet_name = ExcelDataNode(
     excel_data_node_as_numpy_no_sheet_name = ExcelDataNode(
         "bar",
         "bar",
         Scope.SCENARIO,
         Scope.SCENARIO,
-        properties={"path": path, "exposed_type": "numpy"},
+        properties={"path": excel_file_path, "exposed_type": "numpy"},
     )
     )
 
 
     data_numpy_no_sheet_name = excel_data_node_as_numpy_no_sheet_name.read()
     data_numpy_no_sheet_name = excel_data_node_as_numpy_no_sheet_name.read()
@@ -242,23 +351,15 @@ def test_read_multi_sheet_with_header():
         assert isinstance(data_numpy_no_sheet_name[key], np.ndarray)
         assert isinstance(data_numpy_no_sheet_name[key], np.ndarray)
         assert np.array_equal(data_numpy[key], data_numpy_no_sheet_name[key])
         assert np.array_equal(data_numpy[key], data_numpy_no_sheet_name[key])
 
 
-    # Create the same ExcelDataNode but with custom exposed_type
-    non_existing_sheet_name_custom = ExcelDataNode(
-        "bar",
-        Scope.SCENARIO,
-        properties={
-            "path": path,
-            "sheet_name": ["Sheet1", "xyz"],
-            "exposed_type": MyCustomObject1,
-        },
-    )
-    with pytest.raises(NonExistingExcelSheet):
-        non_existing_sheet_name_custom.read()
 
 
+def test_read_multi_sheet_with_header_single_custom_exposed_type():
+    data_pandas = pd.read_excel(excel_file_path, sheet_name=sheet_names)
+
+    # With sheet name
     excel_data_node_as_custom_object = ExcelDataNode(
     excel_data_node_as_custom_object = ExcelDataNode(
         "bar",
         "bar",
         Scope.SCENARIO,
         Scope.SCENARIO,
-        properties={"path": path, "sheet_name": sheet_names, "exposed_type": MyCustomObject1},
+        properties={"path": excel_file_path, "sheet_name": sheet_names, "exposed_type": MyCustomObject1},
     )
     )
 
 
     data_custom = excel_data_node_as_custom_object.read()
     data_custom = excel_data_node_as_custom_object.read()
@@ -275,10 +376,11 @@ def test_read_multi_sheet_with_header():
             assert row_pandas["integer"] == row_custom.integer
             assert row_pandas["integer"] == row_custom.integer
             assert row_pandas["text"] == row_custom.text
             assert row_pandas["text"] == row_custom.text
 
 
+    # Without sheet name
     excel_data_node_as_custom_object_no_sheet_name = ExcelDataNode(
     excel_data_node_as_custom_object_no_sheet_name = ExcelDataNode(
         "bar",
         "bar",
         Scope.SCENARIO,
         Scope.SCENARIO,
-        properties={"path": path, "exposed_type": MyCustomObject1},
+        properties={"path": excel_file_path, "exposed_type": MyCustomObject1},
     )
     )
 
 
     data_custom_no_sheet_name = excel_data_node_as_custom_object_no_sheet_name.read()
     data_custom_no_sheet_name = excel_data_node_as_custom_object_no_sheet_name.read()
@@ -297,31 +399,26 @@ def test_read_multi_sheet_with_header():
             assert row_custom_no_sheet_name.integer == row_custom.integer
             assert row_custom_no_sheet_name.integer == row_custom.integer
             assert row_custom_no_sheet_name.text == row_custom.text
             assert row_custom_no_sheet_name.text == row_custom.text
 
 
-    with pytest.raises(ExposedTypeLengthMismatch):
-        dn = ExcelDataNode(
-            "bar",
-            Scope.SCENARIO,
-            properties={
-                "path": path,
-                "sheet_name": ["Sheet1"],
-                "exposed_type": [MyCustomObject1, MyCustomObject2],
-            },
-        )
-        dn.read()
 
 
-    custom_class_dict = {"Sheet1": MyCustomObject1, "Sheet2": MyCustomObject2}
+def test_read_multi_sheet_with_header_multiple_custom_exposed_type():
+    data_pandas = pd.read_excel(excel_file_path, sheet_name=sheet_names)
 
 
+    # With sheet name
     excel_data_node_as_multi_custom_object = ExcelDataNode(
     excel_data_node_as_multi_custom_object = ExcelDataNode(
         "bar",
         "bar",
         Scope.SCENARIO,
         Scope.SCENARIO,
-        properties={"path": path, "sheet_name": sheet_names, "exposed_type": custom_class_dict},
+        properties={"path": excel_file_path, "sheet_name": sheet_names, "exposed_type": custom_class_dict},
     )
     )
     assert excel_data_node_as_multi_custom_object.properties["exposed_type"] == custom_class_dict
     assert excel_data_node_as_multi_custom_object.properties["exposed_type"] == custom_class_dict
 
 
     excel_data_node_as_multi_custom_object = ExcelDataNode(
     excel_data_node_as_multi_custom_object = ExcelDataNode(
         "bar",
         "bar",
         Scope.SCENARIO,
         Scope.SCENARIO,
-        properties={"path": path, "sheet_name": sheet_names, "exposed_type": [MyCustomObject1, MyCustomObject2]},
+        properties={
+            "path": excel_file_path,
+            "sheet_name": sheet_names,
+            "exposed_type": [MyCustomObject1, MyCustomObject2],
+        },
     )
     )
     assert excel_data_node_as_multi_custom_object.properties["exposed_type"] == [MyCustomObject1, MyCustomObject2]
     assert excel_data_node_as_multi_custom_object.properties["exposed_type"] == [MyCustomObject1, MyCustomObject2]
 
 
@@ -339,10 +436,11 @@ def test_read_multi_sheet_with_header():
             assert row_pandas["integer"] == row_custom.integer
             assert row_pandas["integer"] == row_custom.integer
             assert row_pandas["text"] == row_custom.text
             assert row_pandas["text"] == row_custom.text
 
 
+    # Without sheet name
     excel_data_node_as_multi_custom_object_no_sheet_name = ExcelDataNode(
     excel_data_node_as_multi_custom_object_no_sheet_name = ExcelDataNode(
         "bar",
         "bar",
         Scope.SCENARIO,
         Scope.SCENARIO,
-        properties={"path": path, "exposed_type": custom_class_dict},
+        properties={"path": excel_file_path, "exposed_type": custom_class_dict},
     )
     )
     assert excel_data_node_as_multi_custom_object_no_sheet_name.properties["exposed_type"] == custom_class_dict
     assert excel_data_node_as_multi_custom_object_no_sheet_name.properties["exposed_type"] == custom_class_dict
 
 
@@ -363,22 +461,10 @@ def test_read_multi_sheet_with_header():
             assert row_custom_no_sheet_name.text == row_custom.text
             assert row_custom_no_sheet_name.text == row_custom.text
 
 
 
 
-def test_read_multi_sheet_without_header():
-    not_existing_excel = ExcelDataNode(
-        "foo",
-        Scope.SCENARIO,
-        properties={"path": "WRONG.xlsx", "has_header": False, "sheet_name": ["sheet_name_1", "sheet_name_2"]},
-    )
-    with pytest.raises(NoData):
-        assert not_existing_excel.read() is None
-        not_existing_excel.read_or_raise()
-
-    path = os.path.join(pathlib.Path(__file__).parent.resolve(), "data_sample/example.xlsx")
-    sheet_names = ["Sheet1", "Sheet2"]
-
-    # Create ExcelDataNode without exposed_type (Default is pandas.DataFrame)
+def test_read_multi_sheet_without_header_pandas():
+    # With sheet name
     excel_data_node_as_pandas = ExcelDataNode(
     excel_data_node_as_pandas = ExcelDataNode(
-        "bar", Scope.SCENARIO, properties={"path": path, "has_header": False, "sheet_name": sheet_names}
+        "bar", Scope.SCENARIO, properties={"path": excel_file_path, "has_header": False, "sheet_name": sheet_names}
     )
     )
     data_pandas = excel_data_node_as_pandas.read()
     data_pandas = excel_data_node_as_pandas.read()
     assert isinstance(data_pandas, Dict)
     assert isinstance(data_pandas, Dict)
@@ -387,22 +473,29 @@ def test_read_multi_sheet_without_header():
     assert list(data_pandas.keys()) == sheet_names
     assert list(data_pandas.keys()) == sheet_names
     for sheet_name in sheet_names:
     for sheet_name in sheet_names:
         assert isinstance(data_pandas[sheet_name], pd.DataFrame)
         assert isinstance(data_pandas[sheet_name], pd.DataFrame)
-        assert data_pandas[sheet_name].equals(pd.read_excel(path, header=None, sheet_name=sheet_name))
+        assert pd.DataFrame.equals(
+            data_pandas[sheet_name], pd.read_excel(excel_file_path, header=None, sheet_name=sheet_name)
+        )
 
 
+    # Without sheet name
     excel_data_node_as_pandas_no_sheet_name = ExcelDataNode(
     excel_data_node_as_pandas_no_sheet_name = ExcelDataNode(
-        "bar", Scope.SCENARIO, properties={"path": path, "has_header": False}
+        "bar", Scope.SCENARIO, properties={"path": excel_file_path, "has_header": False}
     )
     )
     data_pandas_no_sheet_name = excel_data_node_as_pandas_no_sheet_name.read()
     data_pandas_no_sheet_name = excel_data_node_as_pandas_no_sheet_name.read()
     assert isinstance(data_pandas_no_sheet_name, Dict)
     assert isinstance(data_pandas_no_sheet_name, Dict)
     for key in data_pandas_no_sheet_name.keys():
     for key in data_pandas_no_sheet_name.keys():
         assert isinstance(data_pandas_no_sheet_name[key], pd.DataFrame)
         assert isinstance(data_pandas_no_sheet_name[key], pd.DataFrame)
-        assert data_pandas[key].equals(data_pandas_no_sheet_name[key])
+        assert pd.DataFrame.equals(data_pandas[key], data_pandas_no_sheet_name[key])
+
 
 
-    # Create ExcelDataNode with numpy exposed_type
+def test_read_multi_sheet_without_header_numpy():
+    data_pandas = pd.read_excel(excel_file_path, header=None, sheet_name=sheet_names)
+
+    # With sheet name
     excel_data_node_as_numpy = ExcelDataNode(
     excel_data_node_as_numpy = ExcelDataNode(
         "bar",
         "bar",
         Scope.SCENARIO,
         Scope.SCENARIO,
-        properties={"path": path, "has_header": False, "sheet_name": sheet_names, "exposed_type": "numpy"},
+        properties={"path": excel_file_path, "has_header": False, "sheet_name": sheet_names, "exposed_type": "numpy"},
     )
     )
 
 
     data_numpy = excel_data_node_as_numpy.read()
     data_numpy = excel_data_node_as_numpy.read()
@@ -415,13 +508,14 @@ def test_read_multi_sheet_without_header():
     assert list(data_numpy.keys()) == sheet_names
     assert list(data_numpy.keys()) == sheet_names
     for sheet_name in sheet_names:
     for sheet_name in sheet_names:
         assert np.array_equal(
         assert np.array_equal(
-            data_pandas[sheet_name], pd.read_excel(path, header=None, sheet_name=sheet_name).to_numpy()
+            data_pandas[sheet_name], pd.read_excel(excel_file_path, header=None, sheet_name=sheet_name).to_numpy()
         )
         )
 
 
+    # Without sheet name
     excel_data_node_as_numpy_no_sheet_name = ExcelDataNode(
     excel_data_node_as_numpy_no_sheet_name = ExcelDataNode(
         "bar",
         "bar",
         Scope.SCENARIO,
         Scope.SCENARIO,
-        properties={"path": path, "has_header": False, "exposed_type": "numpy"},
+        properties={"path": excel_file_path, "has_header": False, "exposed_type": "numpy"},
     )
     )
 
 
     data_numpy_no_sheet_name = excel_data_node_as_numpy_no_sheet_name.read()
     data_numpy_no_sheet_name = excel_data_node_as_numpy_no_sheet_name.read()
@@ -430,25 +524,16 @@ def test_read_multi_sheet_without_header():
         assert isinstance(data_numpy_no_sheet_name[key], np.ndarray)
         assert isinstance(data_numpy_no_sheet_name[key], np.ndarray)
         assert np.array_equal(data_numpy[key], data_numpy_no_sheet_name[key])
         assert np.array_equal(data_numpy[key], data_numpy_no_sheet_name[key])
 
 
-    # Create the same ExcelDataNode but with custom exposed_type
-    non_existing_sheet_name_custom = ExcelDataNode(
-        "bar",
-        Scope.SCENARIO,
-        properties={
-            "path": path,
-            "has_header": False,
-            "sheet_name": ["Sheet1", "xyz"],
-            "exposed_type": MyCustomObject1,
-        },
-    )
-    with pytest.raises(NonExistingExcelSheet):
-        non_existing_sheet_name_custom.read()
 
 
+def test_read_multi_sheet_without_header_single_custom_exposed_type():
+    data_pandas = pd.read_excel(excel_file_path, header=None, sheet_name=sheet_names)
+
+    # With sheet name
     excel_data_node_as_custom_object = ExcelDataNode(
     excel_data_node_as_custom_object = ExcelDataNode(
         "bar",
         "bar",
         Scope.SCENARIO,
         Scope.SCENARIO,
         properties={
         properties={
-            "path": path,
+            "path": excel_file_path,
             "has_header": False,
             "has_header": False,
             "sheet_name": sheet_names,
             "sheet_name": sheet_names,
             "exposed_type": MyCustomObject1,
             "exposed_type": MyCustomObject1,
@@ -470,10 +555,11 @@ def test_read_multi_sheet_without_header():
             assert row_pandas[1] == row_custom.integer
             assert row_pandas[1] == row_custom.integer
             assert row_pandas[2] == row_custom.text
             assert row_pandas[2] == row_custom.text
 
 
+    # Without sheet name
     excel_data_node_as_custom_object_no_sheet_name = ExcelDataNode(
     excel_data_node_as_custom_object_no_sheet_name = ExcelDataNode(
         "bar",
         "bar",
         Scope.SCENARIO,
         Scope.SCENARIO,
-        properties={"path": path, "has_header": False, "exposed_type": MyCustomObject1},
+        properties={"path": excel_file_path, "has_header": False, "exposed_type": MyCustomObject1},
     )
     )
 
 
     data_custom_no_sheet_name = excel_data_node_as_custom_object_no_sheet_name.read()
     data_custom_no_sheet_name = excel_data_node_as_custom_object_no_sheet_name.read()
@@ -492,26 +578,16 @@ def test_read_multi_sheet_without_header():
             assert row_custom_no_sheet_name.integer == row_custom.integer
             assert row_custom_no_sheet_name.integer == row_custom.integer
             assert row_custom_no_sheet_name.text == row_custom.text
             assert row_custom_no_sheet_name.text == row_custom.text
 
 
-    with pytest.raises(ExposedTypeLengthMismatch):
-        dn = ExcelDataNode(
-            "bar",
-            Scope.SCENARIO,
-            properties={
-                "path": path,
-                "sheet_name": ["Sheet1"],
-                "exposed_type": [MyCustomObject1, MyCustomObject2],
-                "has_header": False,
-            },
-        )
-        dn.read()
 
 
-    custom_class_dict = {"Sheet1": MyCustomObject1, "Sheet2": MyCustomObject2}
+def test_read_multi_sheet_without_header_multiple_custom_exposed_type():
+    data_pandas = pd.read_excel(excel_file_path, header=None, sheet_name=sheet_names)
 
 
+    # With sheet names
     excel_data_node_as_multi_custom_object = ExcelDataNode(
     excel_data_node_as_multi_custom_object = ExcelDataNode(
         "bar",
         "bar",
         Scope.SCENARIO,
         Scope.SCENARIO,
         properties={
         properties={
-            "path": path,
+            "path": excel_file_path,
             "sheet_name": sheet_names,
             "sheet_name": sheet_names,
             "exposed_type": custom_class_dict,
             "exposed_type": custom_class_dict,
             "has_header": False,
             "has_header": False,
@@ -523,7 +599,7 @@ def test_read_multi_sheet_without_header():
         "bar",
         "bar",
         Scope.SCENARIO,
         Scope.SCENARIO,
         properties={
         properties={
-            "path": path,
+            "path": excel_file_path,
             "sheet_name": sheet_names,
             "sheet_name": sheet_names,
             "exposed_type": [MyCustomObject1, MyCustomObject2],
             "exposed_type": [MyCustomObject1, MyCustomObject2],
             "has_header": False,
             "has_header": False,
@@ -545,10 +621,11 @@ def test_read_multi_sheet_without_header():
             assert row_pandas[1] == row_custom.integer
             assert row_pandas[1] == row_custom.integer
             assert row_pandas[2] == row_custom.text
             assert row_pandas[2] == row_custom.text
 
 
+    # Without sheet names
     excel_data_node_as_multi_custom_object_no_sheet_name = ExcelDataNode(
     excel_data_node_as_multi_custom_object_no_sheet_name = ExcelDataNode(
         "bar",
         "bar",
         Scope.SCENARIO,
         Scope.SCENARIO,
-        properties={"path": path, "has_header": False, "exposed_type": custom_class_dict},
+        properties={"path": excel_file_path, "has_header": False, "exposed_type": custom_class_dict},
     )
     )
 
 
     multi_data_custom_no_sheet_name = excel_data_node_as_multi_custom_object_no_sheet_name.read()
     multi_data_custom_no_sheet_name = excel_data_node_as_multi_custom_object_no_sheet_name.read()