Repository: sanders41/sas7bdat-converter

Issue:
Add option to specify format
Add an option to specify if the files are sas7bdat or xpt format.


Discussion:

Resolving patch:
diff --git a/sas7bdat_converter/converter.py b/sas7bdat_converter/converter.py
--- a/sas7bdat_converter/converter.py
+++ b/sas7bdat_converter/converter.py
@@ -22,7 +22,7 @@ def batch_to_csv(
     continue_on_error: bool = False,
 ) -> None:
     """
-    Converts a batch of sas7bdat files to csv files.
+    Converts a batch of sas7bdat and/or xpt files to csv files.
 
     Args:
         file_dicts: A list dictionaries containing the files to convert. The dictionary should
@@ -42,13 +42,13 @@ def batch_to_csv(
     for file_dict in file_dicts:
         _rise_on_invalid_file_dict(file_dict)
 
-        sas7bdat = _format_path(file_dict["sas7bdat_file"])
+        xpt = _format_path(file_dict["sas7bdat_file"])
         export = _format_path(file_dict["export_file"])
         try:
-            to_csv(sas7bdat_file=sas7bdat, export_file=export)
+            to_csv(sas7bdat_file=xpt, export_file=export)
         except:  # noqa: E722
             if continue_on_error:
-                logger.info(f"Error converting {sas7bdat}")
+                logger.info(f"Error converting {xpt}")
             else:
                 raise
 
@@ -58,7 +58,7 @@ def batch_to_excel(
     continue_on_error: bool = False,
 ) -> None:
     """
-    Converts a batch of sas7bdat files to xlsx files.
+    Converts a batch of sas7bdat and/or xpt files to xlsx files.
 
     Args:
         file_dicts: A list of dictionaries containing the files to convert. The dictionary should
@@ -94,7 +94,7 @@ def batch_to_json(
     continue_on_error: bool = False,
 ) -> None:
     """
-    Converts a batch of sas7bdat files to json files.
+    Converts a batch of sas7bdat and/or xpt files to json files.
 
     Args:
         file_dicts: A list dictionaries containing the files to convert. The dictionary should
@@ -130,7 +130,7 @@ def batch_to_xml(
     continue_on_error: bool = False,
 ) -> None:
     """
-    Converts a batch of sas7bdat files to xml files.
+    Converts a batch of sas7bdat and/or xpt files to xml files.
 
     Args:
         file_dicts: A list dictionaries containing the files to convert. The dictionary should
@@ -216,7 +216,7 @@ def dir_to_csv(
     continue_on_error: bool = False,
 ) -> None:
     """
-    Converts all sas7bdat files in a directory into csv files.
+    Converts all sas7bdat and/or xpt files in a directory into csv files.
 
     args:
         dir_path: The path to the directory that contains the sas7bdat files
@@ -236,7 +236,7 @@ def dir_to_excel(
     continue_on_error: bool = False,
 ) -> None:
     """
-    Converts all sas7bdat files in a directory into xlsx files.
+    Converts all sas7bdat and/or xpt files in a directory into xlsx files.
 
     args:
         dir_path: The path to the directory that contains the sas7bdat files
@@ -256,7 +256,7 @@ def dir_to_json(
     continue_on_error: bool = False,
 ) -> None:
     """
-    Converts all sas7bdat files in a directory into json files.
+    Converts all sas7bdat and/or xpt files in a directory into json files.
 
     args:
         dir_path: The path to the directory that contains the sas7bdat files
@@ -276,7 +276,7 @@ def dir_to_xml(
     continue_on_error: bool = False,
 ) -> None:
     """
-    Converts all sas7bdat files in a directory into xml files.
+    Converts all sas7bdat and/or xpt files in a directory into xml files.
 
     args:
         dir_path: The path to the directory that contains the sas7bdat files
@@ -292,7 +292,7 @@ def dir_to_xml(
 
 def to_csv(sas7bdat_file: Union[str, Path], export_file: Union[str, Path]) -> None:
     """
-    Converts a sas7bdat file into a csv file.
+    Converts a sas7bdat and/or xpt file into a csv file.
 
     args:
         sas7bdat_file: The name, including the path, for the sas7bdat file.
@@ -311,7 +311,7 @@ def to_csv(sas7bdat_file: Union[str, Path], export_file: Union[str, Path]) -> No
 
 def to_dataframe(sas7bdat_file: Union[str, Path]) -> pd.DataFrame:
     """
-    Converts a sas7bdat file into a pandas dataframe.
+    Converts a sas7bdat and/or xpt file into a pandas dataframe.
 
     args:
         sas7bdat_file: The name, including the path, for the sas7bdat file.
@@ -335,7 +335,7 @@ def to_dataframe(sas7bdat_file: Union[str, Path]) -> pd.DataFrame:
 
 def to_excel(sas7bdat_file: Union[str, Path], export_file: Union[str, Path]) -> None:
     """
-    Converts a sas7bdat file into a xlsx file.
+    Converts a sas7bdat and/or xpt file into a xlsx file.
 
     args:
         sas7bdat_file: The name, including the path, for the sas7bdat file.
@@ -354,7 +354,7 @@ def to_excel(sas7bdat_file: Union[str, Path], export_file: Union[str, Path]) ->
 
 def to_json(sas7bdat_file: Union[str, Path], export_file: Union[str, Path]) -> None:
     """
-    Converts a sas7bdat file into a json file.
+    Converts a sas7bdat and/or xpt file into a json file.
 
     args:
         sas7bdat_file: The name, including the path, for the sas7bdat file.
@@ -378,7 +378,7 @@ def to_xml(
     first_node: str = "item",
 ) -> None:
     """
-    Converts a sas7bdat file into a xml file.
+    Converts a sas7bdat and/or xpt file into a xml file.
 
     args:
         sas7bdat_file: The name, including the path, for the sas7bdat file.
@@ -460,7 +460,7 @@ def _walk_dir(
 ) -> None:
     path = dir_path if isinstance(dir_path, Path) else Path(dir_path)
     for file_name in path.iterdir():
-        if file_name.suffix == ".sas7bdat":
+        if file_name.suffix in [".sas7bdat", ".xpt"]:
             export_file = Path(f"{file_name.stem}.{file_type}")
             if export_path:
                 export_file = Path(export_path).joinpath(export_file)
@@ -472,10 +472,10 @@ def _walk_dir(
             try:
                 if file_type == "csv":
                     to_csv(str(sas7bdat_file), str(export_file))
-                elif file_type == "xlsx":
-                    to_excel(str(sas7bdat_file), str(export_file))
                 elif file_type == "json":
                     to_json(str(sas7bdat_file), str(export_file))
+                elif file_type == "xlsx":
+                    to_excel(str(sas7bdat_file), str(export_file))
                 elif file_type == "xml":
                     to_xml(str(sas7bdat_file), str(export_file))
             except:  # noqa: 722


Test patch:
diff --git a/tests/assets/bad_sas_files/bad_xpt_file.xpt b/tests/assets/bad_sas_files/bad_xpt_file.xpt
new file mode 100644
diff --git a/tests/assets/expected_xpt/file1.csv b/tests/assets/expected_xpt/file1.csv
new file mode 100644
--- /dev/null
+++ b/tests/assets/expected_xpt/file1.csv
@@ -0,0 +1,3 @@
+"irow", "trow", "frow"
+1, "Some text", 1.5
+2, "Some more test", 17.23
diff --git a/tests/assets/expected_xpt/file1.json b/tests/assets/expected_xpt/file1.json
new file mode 100644
--- /dev/null
+++ b/tests/assets/expected_xpt/file1.json
@@ -0,0 +1,5 @@
+{
+  "irow": [1, 2],
+  "trow": ["Some text", "Some more test"],
+  "frow": [1.5, 17.23]
+}
diff --git a/tests/assets/expected_xpt/file1.xlsx b/tests/assets/expected_xpt/file1.xlsx
new file mode 100644
Binary files /dev/null and b/tests/assets/expected_xpt/file1.xlsx differ
diff --git a/tests/assets/expected_xpt/file1.xml b/tests/assets/expected_xpt/file1.xml
new file mode 100644
--- /dev/null
+++ b/tests/assets/expected_xpt/file1.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<root>
+  <item>
+    <irow>1</irow>
+    <trow>Some text</trow>
+    <frow>1.5</frow>
+  </item>
+  <item>
+    <irow>2</irow>
+    <trow>Some more test</trow>
+    <frow>17.23</frow>
+  </item>
+</root>
diff --git a/tests/assets/expected_xpt/file2.csv b/tests/assets/expected_xpt/file2.csv
new file mode 100644
--- /dev/null
+++ b/tests/assets/expected_xpt/file2.csv
@@ -0,0 +1,4 @@
+"irow", "trow", "frow"
+3, "text 1", 21.50
+4, "text 2", 19.21
+5, "text 3", 42.42
diff --git a/tests/assets/expected_xpt/file2.json b/tests/assets/expected_xpt/file2.json
new file mode 100644
--- /dev/null
+++ b/tests/assets/expected_xpt/file2.json
@@ -0,0 +1,5 @@
+{
+  "irow": [3, 4, 5],
+  "trow": ["text 1", "text 2", "text 3"],
+  "frow": [21.50, 19.21, 42.42]
+}
diff --git a/tests/assets/expected_xpt/file2.xlsx b/tests/assets/expected_xpt/file2.xlsx
new file mode 100644
Binary files /dev/null and b/tests/assets/expected_xpt/file2.xlsx differ
diff --git a/tests/assets/expected_xpt/file2.xml b/tests/assets/expected_xpt/file2.xml
new file mode 100644
--- /dev/null
+++ b/tests/assets/expected_xpt/file2.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<root>
+  <item>
+    <irow>3</irow>
+    <trow>text 1</trow>
+    <frow>21.50</frow>
+  </item>
+  <item>
+    <irow>4</irow>
+    <trow>text 2</trow>
+    <frow>19.21</frow>
+  </item>
+  <item>
+    <irow>5</irow>
+    <trow>text 3</trow>
+    <frow>42.42</frow>
+  </item>
+</root>
diff --git a/tests/assets/xpt_files/file1.xpt b/tests/assets/xpt_files/file1.xpt
new file mode 100644
Binary files /dev/null and b/tests/assets/xpt_files/file1.xpt differ
diff --git a/tests/assets/xpt_files/file2.xpt b/tests/assets/xpt_files/file2.xpt
new file mode 100644
Binary files /dev/null and b/tests/assets/xpt_files/file2.xpt differ
diff --git a/tests/conftest.py b/tests/conftest.py
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -2,34 +2,59 @@
 
 import pytest
 
-SAS7BDAT_DIR = Path().absolute().joinpath("tests/assets/sas7bdat_files")
+ASSETS_DIR = Path().absolute().joinpath("tests/assets")
 
 
-@pytest.fixture(scope="session")
+@pytest.fixture(scope="module")
 def expected_dir():
-    return Path().absolute().joinpath("tests/assets/expected_files")
+    return ASSETS_DIR / "expected_files"
 
 
-@pytest.fixture(scope="session")
+@pytest.fixture(scope="module")
 def sas_file_1():
-    return SAS7BDAT_DIR.joinpath("file1.sas7bdat")
+    return ASSETS_DIR.joinpath("sas7bdat_files/file1.sas7bdat")
 
 
-@pytest.fixture(scope="session")
+@pytest.fixture(scope="module")
 def sas_file_2():
-    return SAS7BDAT_DIR.joinpath("file2.sas7bdat")
+    return ASSETS_DIR.joinpath("sas7bdat_files/file2.sas7bdat")
 
 
-@pytest.fixture(scope="session")
+@pytest.fixture(scope="module")
 def sas_file_3():
-    return SAS7BDAT_DIR.joinpath("file3.sas7bdat")
+    return ASSETS_DIR.joinpath("sas7bdat_files/file3.sas7bdat")
 
 
-@pytest.fixture(scope="session")
+@pytest.fixture(scope="module")
 def sas7bdat_dir():
-    return SAS7BDAT_DIR
+    return ASSETS_DIR / "sas7bdat_files"
 
 
-@pytest.fixture(scope="session")
+@pytest.fixture
 def bad_sas_file():
-    return Path().absolute().joinpath("tests/assets/bad_sas_files/bad_sas_file.sas7bdat")
+    return ASSETS_DIR.joinpath("bad_sas_files/bad_sas_file.sas7bdat")
+
+
+@pytest.fixture(scope="module")
+def xpt_file_1():
+    return ASSETS_DIR.joinpath("xpt_files/file1.xpt")
+
+
+@pytest.fixture(scope="module")
+def xpt_file_2():
+    return ASSETS_DIR.joinpath("xpt_files/file2.xpt")
+
+
+@pytest.fixture(scope="module")
+def xpt_dir():
+    return ASSETS_DIR / "xpt_files"
+
+
+@pytest.fixture
+def bad_xpt_file():
+    return ASSETS_DIR.joinpath("bad_sas_files/bad_xpt_file.xpt")
+
+
+@pytest.fixture(scope="module")
+def xpt_expected_dir():
+    return ASSETS_DIR / "expected_xpt"
diff --git a/tests/test_sas7bdat_converter.py b/tests/test_sas7bdat_converter.py
--- a/tests/test_sas7bdat_converter.py
+++ b/tests/test_sas7bdat_converter.py
@@ -11,7 +11,7 @@
 current_dir = Path().absolute()
 
 
-def test_batch_to_csv_path(tmp_path, sas_file_1, sas_file_2, sas_file_3):
+def test_batch_to_csv_path_sas(tmp_path, sas_file_1, sas_file_2, sas_file_3):
     converted_file_1 = tmp_path.joinpath("file1.csv")
     converted_file_2 = tmp_path.joinpath("file2.csv")
     converted_file_3 = tmp_path.joinpath("file3.csv")
@@ -32,7 +32,26 @@ def test_batch_to_csv_path(tmp_path, sas_file_1, sas_file_2, sas_file_3):
     assert files_created
 
 
-def test_batch_to_csv_str(tmp_path, sas_file_1, sas_file_2, sas_file_3):
+def test_batch_to_csv_path_xpt(tmp_path, xpt_file_1, xpt_file_2):
+    converted_file_1 = tmp_path.joinpath("file1.csv")
+    converted_file_2 = tmp_path.joinpath("file2.csv")
+
+    file_dict = [
+        {"sas7bdat_file": xpt_file_1, "export_file": converted_file_1},
+        {"sas7bdat_file": xpt_file_2, "export_file": converted_file_2},
+    ]
+
+    sas7bdat_converter.batch_to_csv(file_dict)
+
+    files_created = False
+
+    if converted_file_1.is_file() and converted_file_2.is_file():
+        files_created = True
+
+    assert files_created
+
+
+def test_batch_to_csv_str_sas(tmp_path, sas_file_1, sas_file_2, sas_file_3):
     converted_file_1 = tmp_path.joinpath("file1.csv")
     converted_file_2 = tmp_path.joinpath("file2.csv")
     converted_file_3 = tmp_path.joinpath("file3.csv")
@@ -53,7 +72,26 @@ def test_batch_to_csv_str(tmp_path, sas_file_1, sas_file_2, sas_file_3):
     assert files_created
 
 
-def test_batch_to_csv_continue(tmp_path, caplog, sas_file_1):
+def test_batch_to_csv_str_xpt(tmp_path, xpt_file_1, xpt_file_2):
+    converted_file_1 = tmp_path.joinpath("file1.csv")
+    converted_file_2 = tmp_path.joinpath("file2.csv")
+
+    file_dict = [
+        {"sas7bdat_file": str(xpt_file_1), "export_file": str(converted_file_1)},
+        {"sas7bdat_file": str(xpt_file_2), "export_file": str(converted_file_2)},
+    ]
+
+    sas7bdat_converter.batch_to_csv(file_dict)
+
+    files_created = False
+
+    if converted_file_1.is_file() and converted_file_2.is_file():
+        files_created = True
+
+    assert files_created
+
+
+def test_batch_to_csv_continue_sas(tmp_path, caplog, sas_file_1):
     bad_sas_file = tmp_path.joinpath("bad_file.sas7bdat")
     bad_converted_file = tmp_path.joinpath("bad_file.csv")
     converted_file = tmp_path.joinpath("file1.csv")
@@ -69,7 +107,23 @@ def test_batch_to_csv_continue(tmp_path, caplog, sas_file_1):
     assert "Error converting" in caplog.text
 
 
-def test_batch_to_csv_no_continue(tmp_path, caplog, sas_file_1):
+def test_batch_to_csv_continue_xpt(tmp_path, caplog, xpt_file_1):
+    bad_xpt_file = tmp_path.joinpath("bad_file.xpt")
+    bad_converted_file = tmp_path.joinpath("bad_file.csv")
+    converted_file = tmp_path.joinpath("file1.csv")
+
+    file_dict = [
+        {"sas7bdat_file": bad_xpt_file, "export_file": bad_converted_file},
+        {"sas7bdat_file": xpt_file_1, "export_file": converted_file},
+    ]
+
+    sas7bdat_converter.batch_to_csv(file_dict, continue_on_error=True)
+
+    assert converted_file.is_file()
+    assert "Error converting" in caplog.text
+
+
+def test_batch_to_csv_no_continue_sas(tmp_path, sas_file_1):
     bad_sas_file = tmp_path.joinpath("bad_file.sas7bdat")
     bad_converted_file = tmp_path.joinpath("bad_file.csv")
     converted_file = tmp_path.joinpath("file1.csv")
@@ -85,6 +139,22 @@ def test_batch_to_csv_no_continue(tmp_path, caplog, sas_file_1):
     assert execinfo.value
 
 
+def test_batch_to_csv_no_continue_xpt(tmp_path, xpt_file_1):
+    bad_xpt_file = tmp_path.joinpath("bad_file.xpt")
+    bad_converted_file = tmp_path.joinpath("bad_file.csv")
+    converted_file = tmp_path.joinpath("file1.csv")
+
+    file_dict = [
+        {"sas7bdat_file": bad_xpt_file, "export_file": bad_converted_file},
+        {"sas7bdat_file": xpt_file_1, "export_file": converted_file},
+    ]
+
+    with pytest.raises(Exception) as execinfo:
+        sas7bdat_converter.batch_to_csv(file_dict, continue_on_error=False)
+
+    assert execinfo.value
+
+
 file_dicts = [
     [{"bad_key": "test.sas7bdat", "export_file": "test.csv"}],
     [{"sas7bdat_file": "test.sas7bdat", "bad_key": "test.csv"}],
@@ -93,14 +163,29 @@ def test_batch_to_csv_no_continue(tmp_path, caplog, sas_file_1):
 
 
 @pytest.mark.parametrize("file_dict", file_dicts)
-def test_batch_to_csv_invalid_key(file_dict):
+def test_batch_to_csv_invalid_key_sas(file_dict):
+    with pytest.raises(KeyError) as execinfo:
+        sas7bdat_converter.batch_to_csv(file_dict)
+
+    assert "Invalid key provided" in str(execinfo.value)
+
+
+file_dicts = [
+    [{"bad_key": "test.xpt", "export_file": "test.csv"}],
+    [{"sas7bdat_file": "test.xpt", "bad_key": "test.csv"}],
+    [{"sas_bad_key": "test.xptt", "export_bad_key": "test.csv"}],
+]
+
+
+@pytest.mark.parametrize("file_dict", file_dicts)
+def test_batch_to_csv_invalid_key_xpt(file_dict):
     with pytest.raises(KeyError) as execinfo:
         sas7bdat_converter.batch_to_csv(file_dict)
 
     assert "Invalid key provided" in str(execinfo.value)
 
 
-def test_batch_to_excel_path(tmp_path, sas_file_1, sas_file_2, sas_file_3):
+def test_batch_to_excel_path_sas(tmp_path, sas_file_1, sas_file_2, sas_file_3):
     converted_file_1 = tmp_path.joinpath("file1.xlsx")
     converted_file_2 = tmp_path.joinpath("file2.xlsx")
     converted_file_3 = tmp_path.joinpath("file3.xlsx")
@@ -120,7 +205,25 @@ def test_batch_to_excel_path(tmp_path, sas_file_1, sas_file_2, sas_file_3):
     assert files_created
 
 
-def test_batch_to_excel_str(tmp_path, sas_file_1, sas_file_2, sas_file_3):
+def test_batch_to_excel_path_xpt(tmp_path, xpt_file_1, xpt_file_2):
+    converted_file_1 = tmp_path.joinpath("file1.xlsx")
+    converted_file_2 = tmp_path.joinpath("file2.xlsx")
+
+    file_dict = [
+        {"sas7bdat_file": xpt_file_1, "export_file": converted_file_1},
+        {"sas7bdat_file": xpt_file_2, "export_file": converted_file_2},
+    ]
+
+    sas7bdat_converter.batch_to_excel(file_dict)
+    files_created = False
+
+    if converted_file_1.is_file() and converted_file_2.is_file():
+        files_created = True
+
+    assert files_created
+
+
+def test_batch_to_excel_str_sas(tmp_path, sas_file_1, sas_file_2, sas_file_3):
     converted_file_1 = tmp_path.joinpath("file1.xlsx")
     converted_file_2 = tmp_path.joinpath("file2.xlsx")
     converted_file_3 = tmp_path.joinpath("file3.xlsx")
@@ -140,7 +243,25 @@ def test_batch_to_excel_str(tmp_path, sas_file_1, sas_file_2, sas_file_3):
     assert files_created
 
 
-def test_batch_to_excel_continue(tmp_path, caplog, sas_file_1):
+def test_batch_to_excel_str_xpt(tmp_path, xpt_file_1, xpt_file_2):
+    converted_file_1 = tmp_path.joinpath("file1.xlsx")
+    converted_file_2 = tmp_path.joinpath("file2.xlsx")
+
+    file_dict = [
+        {"sas7bdat_file": str(xpt_file_1), "export_file": str(converted_file_1)},
+        {"sas7bdat_file": str(xpt_file_2), "export_file": str(converted_file_2)},
+    ]
+
+    sas7bdat_converter.batch_to_excel(file_dict)
+    files_created = False
+
+    if converted_file_1.is_file() and converted_file_2.is_file():
+        files_created = True
+
+    assert files_created
+
+
+def test_batch_to_excel_continue_sas(tmp_path, caplog, sas_file_1):
     bad_sas_file = tmp_path.joinpath("bad_file.sas7bdat")
     bad_converted_file = tmp_path.joinpath("bad_file.xlsx")
     converted_file = tmp_path.joinpath("file1.xlsx")
@@ -156,7 +277,23 @@ def test_batch_to_excel_continue(tmp_path, caplog, sas_file_1):
     assert "Error converting" in caplog.text
 
 
-def test_batch_to_excel_no_continue(tmp_path, caplog, sas_file_1):
+def test_batch_to_excel_continue_xpt(tmp_path, caplog, xpt_file_1):
+    bad_sas_file = tmp_path.joinpath("bad_file.xpt")
+    bad_converted_file = tmp_path.joinpath("bad_file.xlsx")
+    converted_file = tmp_path.joinpath("file1.xlsx")
+
+    file_dict = [
+        {"sas7bdat_file": bad_sas_file, "export_file": bad_converted_file},
+        {"sas7bdat_file": xpt_file_1, "export_file": converted_file},
+    ]
+
+    sas7bdat_converter.batch_to_excel(file_dict, continue_on_error=True)
+
+    assert converted_file.is_file()
+    assert "Error converting" in caplog.text
+
+
+def test_batch_to_excel_no_continue_sas(tmp_path, sas_file_1):
     bad_sas_file = tmp_path.joinpath("bad_file.sas7bdat")
     bad_converted_file = tmp_path.joinpath("bad_file.xlsx")
     converted_file = tmp_path.joinpath("file1.xlsx")
@@ -172,6 +309,22 @@ def test_batch_to_excel_no_continue(tmp_path, caplog, sas_file_1):
     assert execinfo.value
 
 
+def test_batch_to_excel_no_continue_xpt(tmp_path, xpt_file_1):
+    bad_xpt_file = tmp_path.joinpath("bad_file.xpt")
+    bad_converted_file = tmp_path.joinpath("bad_file.xlsx")
+    converted_file = tmp_path.joinpath("file1.xlsx")
+
+    file_dict = [
+        {"sas7bdat_file": bad_xpt_file, "export_file": bad_converted_file},
+        {"sas7bdat_file": xpt_file_1, "export_file": converted_file},
+    ]
+
+    with pytest.raises(FileNotFoundError) as execinfo:
+        sas7bdat_converter.batch_to_excel(file_dict, continue_on_error=False)
+
+    assert execinfo.value
+
+
 file_dicts = [
     [{"bad_key": "test.sas7bdat", "export_file": "test.xlsx"}],
     [{"sas7bdat_file": "test.sas7bdat", "bad_key": "test.xlsx"}],
@@ -180,14 +333,29 @@ def test_batch_to_excel_no_continue(tmp_path, caplog, sas_file_1):
 
 
 @pytest.mark.parametrize("file_dict", file_dicts)
-def test_batch_to_excel_invalid_key(file_dict):
+def test_batch_to_excel_invalid_key_sas(file_dict):
+    with pytest.raises(KeyError) as execinfo:
+        sas7bdat_converter.batch_to_excel(file_dict)
+
+    assert "Invalid key provided" in str(execinfo.value)
+
+
+file_dicts = [
+    [{"bad_key": "test.xpt", "export_file": "test.xlsx"}],
+    [{"sas7bdat_file": "test.xpt", "bad_key": "test.xlsx"}],
+    [{"sas_bad_key": "test.xptt", "export_bad_key": "test.xlsx"}],
+]
+
+
+@pytest.mark.parametrize("file_dict", file_dicts)
+def test_batch_to_excel_invalid_key_xpt(file_dict):
     with pytest.raises(KeyError) as execinfo:
         sas7bdat_converter.batch_to_excel(file_dict)
 
     assert "Invalid key provided" in str(execinfo.value)
 
 
-def test_batch_to_json_path(tmp_path, sas_file_1, sas_file_2, sas_file_3):
+def test_batch_to_json_path_sas(tmp_path, sas_file_1, sas_file_2, sas_file_3):
     converted_file_1 = tmp_path.joinpath("file1.json")
     converted_file_2 = tmp_path.joinpath("file2.json")
     converted_file_3 = tmp_path.joinpath("file3.json")
@@ -207,7 +375,25 @@ def test_batch_to_json_path(tmp_path, sas_file_1, sas_file_2, sas_file_3):
     assert files_created
 
 
-def test_batch_to_json_path_str(tmp_path, sas_file_1, sas_file_2, sas_file_3):
+def test_batch_to_json_path_xpt(tmp_path, xpt_file_1, xpt_file_2):
+    converted_file_1 = tmp_path.joinpath("file1.json")
+    converted_file_2 = tmp_path.joinpath("file2.json")
+
+    file_dict = [
+        {"sas7bdat_file": xpt_file_1, "export_file": converted_file_1},
+        {"sas7bdat_file": xpt_file_2, "export_file": converted_file_2},
+    ]
+
+    sas7bdat_converter.batch_to_json(file_dict)
+    files_created = False
+
+    if converted_file_1.is_file() and converted_file_2.is_file():
+        files_created = True
+
+    assert files_created
+
+
+def test_batch_to_json_path_str_sas(tmp_path, sas_file_1, sas_file_2, sas_file_3):
     converted_file_1 = tmp_path.joinpath("file1.json")
     converted_file_2 = tmp_path.joinpath("file2.json")
     converted_file_3 = tmp_path.joinpath("file3.json")
@@ -227,7 +413,25 @@ def test_batch_to_json_path_str(tmp_path, sas_file_1, sas_file_2, sas_file_3):
     assert files_created
 
 
-def test_batch_to_json_continue(tmp_path, caplog, sas_file_1):
+def test_batch_to_json_path_str_xpt(tmp_path, xpt_file_1, xpt_file_2):
+    converted_file_1 = tmp_path.joinpath("file1.json")
+    converted_file_2 = tmp_path.joinpath("file2.json")
+
+    file_dict = [
+        {"sas7bdat_file": str(xpt_file_1), "export_file": str(converted_file_1)},
+        {"sas7bdat_file": str(xpt_file_2), "export_file": str(converted_file_2)},
+    ]
+
+    sas7bdat_converter.batch_to_json(file_dict)
+    files_created = False
+
+    if converted_file_1.is_file() and converted_file_2.is_file():
+        files_created = True
+
+    assert files_created
+
+
+def test_batch_to_json_continue_sas(tmp_path, caplog, sas_file_1):
     bad_sas_file = tmp_path.joinpath("bad_file.sas7bdat")
     bad_converted_file = tmp_path.joinpath("bad_file.json")
     converted_file = tmp_path.joinpath("file1.json")
@@ -243,7 +447,23 @@ def test_batch_to_json_continue(tmp_path, caplog, sas_file_1):
     assert "Error converting" in caplog.text
 
 
-def test_batch_to_json_no_continue(tmp_path, caplog, sas_file_1):
+def test_batch_to_json_continue_xpt(tmp_path, caplog, xpt_file_1):
+    bad_xpt_file = tmp_path.joinpath("bad_file.xpt")
+    bad_converted_file = tmp_path.joinpath("bad_file.json")
+    converted_file = tmp_path.joinpath("file1.json")
+
+    file_dict = [
+        {"sas7bdat_file": bad_xpt_file, "export_file": bad_converted_file},
+        {"sas7bdat_file": xpt_file_1, "export_file": converted_file},
+    ]
+
+    sas7bdat_converter.batch_to_json(file_dict, continue_on_error=True)
+
+    assert converted_file.is_file()
+    assert "Error converting" in caplog.text
+
+
+def test_batch_to_json_no_continue_sas(tmp_path, sas_file_1):
     bad_sas_file = tmp_path.joinpath("bad_file.sas7bdat")
     bad_converted_file = tmp_path.joinpath("bad_file.json")
     converted_file = tmp_path.joinpath("file1.json")
@@ -259,6 +479,22 @@ def test_batch_to_json_no_continue(tmp_path, caplog, sas_file_1):
     assert execinfo.value
 
 
+def test_batch_to_json_no_continue_xpt(tmp_path, xpt_file_1):
+    bad_xpt_file = tmp_path.joinpath("bad_file.xpt")
+    bad_converted_file = tmp_path.joinpath("bad_file.json")
+    converted_file = tmp_path.joinpath("file1.json")
+
+    file_dict = [
+        {"sas7bdat_file": bad_xpt_file, "export_file": bad_converted_file},
+        {"sas7bdat_file": xpt_file_1, "export_file": converted_file},
+    ]
+
+    with pytest.raises(Exception) as execinfo:
+        sas7bdat_converter.batch_to_json(file_dict, continue_on_error=False)
+
+    assert execinfo.value
+
+
 file_dicts = [
     [{"bad_key": "test.sas7bdat", "export_file": "test.json"}],
     [{"sas7bdat_file": "test.sas7bdat", "bad_key": "test.json"}],
@@ -267,7 +503,22 @@ def test_batch_to_json_no_continue(tmp_path, caplog, sas_file_1):
 
 
 @pytest.mark.parametrize("file_dict", file_dicts)
-def test_batch_to_json_invalid_key(file_dict):
+def test_batch_to_json_invalid_key_sas(file_dict):
+    with pytest.raises(KeyError) as execinfo:
+        sas7bdat_converter.batch_to_json(file_dict)
+
+    assert "Invalid key provided" in str(execinfo.value)
+
+
+file_dicts = [
+    [{"bad_key": "test.xpt", "export_file": "test.json"}],
+    [{"sas7bdat_file": "test.xpt", "bad_key": "test.json"}],
+    [{"sas_bad_key": "test.xptt", "export_bad_key": "test.json"}],
+]
+
+
+@pytest.mark.parametrize("file_dict", file_dicts)
+def test_batch_to_json_invalid_key_xpt(file_dict):
     with pytest.raises(KeyError) as execinfo:
         sas7bdat_converter.batch_to_json(file_dict)
 
@@ -283,7 +534,7 @@ def test_batch_to_json_invalid_key(file_dict):
 
 
 @pytest.mark.parametrize("optional", optionals)
-def test_batch_to_xml_path(tmp_path, sas_file_1, sas_file_2, sas_file_3, optional):
+def test_batch_to_xml_path_sas(tmp_path, sas_file_1, sas_file_2, sas_file_3, optional):
     converted_file_1 = tmp_path.joinpath("file1.xml")
     converted_file_2 = tmp_path.joinpath("file2.xml")
     converted_file_3 = tmp_path.joinpath("file3.xml")
@@ -371,7 +622,74 @@ def test_batch_to_xml_path(tmp_path, sas_file_1, sas_file_2, sas_file_3, optiona
 
 
 @pytest.mark.parametrize("optional", optionals)
-def test_batch_to_xml_str(tmp_path, sas_file_1, sas_file_2, sas_file_3, optional):
+def test_batch_to_xml_path_xpt(tmp_path, xpt_file_1, xpt_file_2, optional):
+    converted_file_1 = tmp_path.joinpath("file1.xml")
+    converted_file_2 = tmp_path.joinpath("file2.xml")
+
+    if optional.get("root_node") and optional.get("first_node"):
+        file_dict = [
+            {
+                "sas7bdat_file": xpt_file_1,
+                "export_file": converted_file_1,
+                "root_node": optional.get("root_node"),
+                "first_node": optional.get("first_node"),
+            },
+            {
+                "sas7bdat_file": xpt_file_2,
+                "export_file": converted_file_2,
+                "root_node": optional.get("root_node"),
+                "first_node": optional.get("first_node"),
+            },
+        ]
+    elif optional.get("root_node"):
+        file_dict = [
+            {
+                "sas7bdat_file": xpt_file_1,
+                "export_file": converted_file_1,
+                "root_node": optional.get("root_node"),
+            },
+            {
+                "sas7bdat_file": xpt_file_2,
+                "export_file": converted_file_2,
+                "root_node": optional.get("root_node"),
+            },
+        ]
+    elif optional.get("first_node"):
+        file_dict = [
+            {
+                "sas7bdat_file": xpt_file_1,
+                "export_file": converted_file_1,
+                "first_node": optional.get("first_node"),
+            },
+            {
+                "sas7bdat_file": xpt_file_2,
+                "export_file": converted_file_2,
+                "first_node": optional.get("first_node"),
+            },
+        ]
+    else:
+        file_dict = [
+            {
+                "sas7bdat_file": xpt_file_1,
+                "export_file": converted_file_1,
+            },
+            {
+                "sas7bdat_file": xpt_file_2,
+                "export_file": converted_file_2,
+            },
+        ]
+
+    sas7bdat_converter.batch_to_xml(file_dict)
+    files_created = False
+
+    if converted_file_1.is_file() and converted_file_2.is_file():
+        files_created = True
+
+    assert files_created
+
+
+@pytest.mark.parametrize("optional", optionals)
+def test_batch_to_xml_str_sas(tmp_path, sas_file_1, sas_file_2, sas_file_3, optional):
     converted_file_1 = tmp_path.joinpath("file1.xml")
     converted_file_2 = tmp_path.joinpath("file2.xml")
     converted_file_3 = tmp_path.joinpath("file3.xml")
@@ -458,14 +776,97 @@ def test_batch_to_xml_str(tmp_path, sas_file_1, sas_file_2, sas_file_3, optional
     assert files_created
 
 
-def test_batch_to_xml_continue(tmp_path, caplog, sas_file_1):
-    bad_sas_file = tmp_path.joinpath("bad_file.sas7bdat")
+@pytest.mark.parametrize("optional", optionals)
+def test_batch_to_xml_str_xpt(tmp_path, xpt_file_1, xpt_file_2, optional):
+    converted_file_1 = tmp_path.joinpath("file1.xml")
+    converted_file_2 = tmp_path.joinpath("file2.xml")
+
+    if optional.get("root_node") and optional.get("first_node"):
+        file_dict = [
+            {
+                "sas7bdat_file": str(xpt_file_1),
+                "export_file": str(converted_file_1),
+                "root_node": optional.get("root_node"),
+                "first_node": optional.get("first_node"),
+            },
+            {
+                "sas7bdat_file": str(xpt_file_2),
+                "export_file": str(converted_file_2),
+                "root_node": optional.get("root_node"),
+                "first_node": optional.get("first_node"),
+            },
+        ]
+    elif optional.get("root_node"):
+        file_dict = [
+            {
+                "sas7bdat_file": str(xpt_file_1),
+                "export_file": str(converted_file_1),
+                "root_node": optional.get("root_node"),
+            },
+            {
+                "sas7bdat_file": str(xpt_file_2),
+                "export_file": str(converted_file_2),
+                "root_node": optional.get("root_node"),
+            },
+        ]
+    elif optional.get("first_node"):
+        file_dict = [
+            {
+                "sas7bdat_file": str(xpt_file_1),
+                "export_file": str(converted_file_1),
+                "first_node": optional.get("first_node"),
+            },
+            {
+                "sas7bdat_file": str(xpt_file_2),
+                "export_file": str(converted_file_2),
+                "first_node": optional.get("first_node"),
+            },
+        ]
+    else:
+        file_dict = [
+            {
+                "sas7bdat_file": str(xpt_file_1),
+                "export_file": str(converted_file_1),
+            },
+            {
+                "sas7bdat_file": str(xpt_file_2),
+                "export_file": str(converted_file_2),
+            },
+        ]
+
+    sas7bdat_converter.batch_to_xml(file_dict)
+    files_created = False
+
+    if converted_file_1.is_file() and converted_file_2.is_file():
+        files_created = True
+
+    assert files_created
+
+
+def test_batch_to_xml_continue_sas(tmp_path, caplog, sas_file_1):
+    bad_sas_file = tmp_path.joinpath("bad_file.sas7bdat")
+    bad_converted_file = tmp_path.joinpath("bad_file.xml")
+    converted_file = tmp_path.joinpath("file1.xml")
+
+    file_dict = [
+        {"sas7bdat_file": bad_sas_file, "export_file": bad_converted_file},
+        {"sas7bdat_file": sas_file_1, "export_file": converted_file},
+    ]
+
+    sas7bdat_converter.batch_to_xml(file_dict, continue_on_error=True)
+
+    assert converted_file.is_file()
+    assert "Error converting" in caplog.text
+
+
+def test_batch_to_xml_continue_xpt(tmp_path, caplog, xpt_file_1):
+    bad_sas_file = tmp_path.joinpath("bad_file.xpt")
     bad_converted_file = tmp_path.joinpath("bad_file.xml")
     converted_file = tmp_path.joinpath("file1.xml")
 
     file_dict = [
         {"sas7bdat_file": bad_sas_file, "export_file": bad_converted_file},
-        {"sas7bdat_file": sas_file_1, "export_file": converted_file},
+        {"sas7bdat_file": xpt_file_1, "export_file": converted_file},
     ]
 
     sas7bdat_converter.batch_to_xml(file_dict, continue_on_error=True)
@@ -474,7 +875,7 @@ def test_batch_to_xml_continue(tmp_path, caplog, sas_file_1):
     assert "Error converting" in caplog.text
 
 
-def test_batch_to_xml_no_continue(tmp_path, caplog, sas_file_1):
+def test_batch_to_xml_no_continue_sas(tmp_path, sas_file_1):
     bad_sas_file = tmp_path.joinpath("bad_file.sas7bdat")
     bad_converted_file = tmp_path.joinpath("bad_file.xml")
     converted_file = tmp_path.joinpath("file1.xml")
@@ -490,6 +891,22 @@ def test_batch_to_xml_no_continue(tmp_path, caplog, sas_file_1):
     assert execinfo.value
 
 
+def test_batch_to_xml_no_continue_xpt(tmp_path, xpt_file_1):
+    bad_sas_file = tmp_path.joinpath("bad_file.xpt")
+    bad_converted_file = tmp_path.joinpath("bad_file.xml")
+    converted_file = tmp_path.joinpath("file1.xml")
+
+    file_dict = [
+        {"sas7bdat_file": bad_sas_file, "export_file": bad_converted_file},
+        {"sas7bdat_file": xpt_file_1, "export_file": converted_file},
+    ]
+
+    with pytest.raises(Exception) as execinfo:
+        sas7bdat_converter.batch_to_xml(file_dict, continue_on_error=False)
+
+    assert execinfo.value
+
+
 file_dicts = [
     [{"bad_key": "test.sas7bdat", "export_file": "test.xml"}],
     [{"sas7bdat_file": "test.sas7bdat", "bad_key": "test.xml"}],
@@ -514,14 +931,45 @@ def test_batch_to_xml_no_continue(tmp_path, caplog, sas_file_1):
 
 
 @pytest.mark.parametrize("file_dict", file_dicts)
-def test_batch_to_xml_invalid_key(file_dict):
+def test_batch_to_xml_invalid_key_sas(file_dict):
+    with pytest.raises(KeyError) as execinfo:
+        sas7bdat_converter.batch_to_xml(file_dict)
+
+    assert "Invalid key provided" in str(execinfo.value)
+
+
+file_dicts = [
+    [{"bad_key": "test.xpt", "export_file": "test.xml"}],
+    [{"sas7bdat_file": "test.xpt", "bad_key": "test.xml"}],
+    [{"sas_bad_key": "test.xptt", "export_bad_key": "test.xml"}],
+    [
+        {
+            "sas7bdat_file": "test.xpt",
+            "export_file": "test.xml",
+            "root_node": "test",
+            "bad": "test",
+        }
+    ],
+    [
+        {
+            "sas7bdat_file": "test.xpt",
+            "export_file": "test.xml",
+            "bad": "test",
+            "first_node": "test",
+        }
+    ],
+]
+
+
+@pytest.mark.parametrize("file_dict", file_dicts)
+def test_batch_to_xml_invalid_key_xpt(file_dict):
     with pytest.raises(KeyError) as execinfo:
         sas7bdat_converter.batch_to_xml(file_dict)
 
     assert "Invalid key provided" in str(execinfo.value)
 
 
-def test_dir_to_csv_same_dir_path(tmp_path, sas7bdat_dir):
+def test_dir_to_csv_same_dir_path_sas(tmp_path, sas7bdat_dir):
     sas_files = [str(x) for x in sas7bdat_dir.iterdir()]
     for sas_file in sas_files:
         shutil.copy(sas_file, str(tmp_path))
@@ -533,7 +981,19 @@ def test_dir_to_csv_same_dir_path(tmp_path, sas7bdat_dir):
     assert sas_counter == convert_counter
 
 
-def test_dir_to_csv_same_dir_str(tmpdir, sas7bdat_dir):
+def test_dir_to_csv_same_dir_path_xpt(tmp_path, xpt_dir):
+    xpt_files = [str(x) for x in xpt_dir.iterdir()]
+    for xpt_file in xpt_files:
+        shutil.copy(xpt_file, str(tmp_path))
+
+    sas7bdat_converter.dir_to_csv(tmp_path)
+    sas_counter = len([name for name in tmp_path.iterdir() if name.suffix == ".xpt"])
+    convert_counter = len([name for name in tmp_path.iterdir() if name.suffix == ".csv"])
+
+    assert sas_counter == convert_counter
+
+
+def test_dir_to_csv_same_dir_str_sas(tmpdir, sas7bdat_dir):
     sas_files = [str(x) for x in sas7bdat_dir.iterdir()]
     for sas_file in sas_files:
         shutil.copy(sas_file, tmpdir)
@@ -545,7 +1005,19 @@ def test_dir_to_csv_same_dir_str(tmpdir, sas7bdat_dir):
     assert sas_counter == convert_counter
 
 
-def test_dir_to_csv_continue(tmp_path, caplog, sas7bdat_dir, bad_sas_file):
+def test_dir_to_csv_same_dir_str_xpt(tmpdir, xpt_dir):
+    xpt_files = [str(x) for x in xpt_dir.iterdir()]
+    for xpt_file in xpt_files:
+        shutil.copy(xpt_file, tmpdir)
+
+    sas7bdat_converter.dir_to_csv(tmpdir)
+    sas_counter = len([name for name in Path(tmpdir).iterdir() if name.suffix == ".xpt"])
+    convert_counter = len([name for name in Path(tmpdir).iterdir() if name.suffix == ".csv"])
+
+    assert sas_counter == convert_counter
+
+
+def test_dir_to_csv_continue_sas(tmp_path, caplog, sas7bdat_dir, bad_sas_file):
     sas_files = [str(x) for x in sas7bdat_dir.iterdir()]
     for sas_file in sas_files:
         shutil.copy(sas_file, str(tmp_path))
@@ -560,7 +1032,22 @@ def test_dir_to_csv_continue(tmp_path, caplog, sas7bdat_dir, bad_sas_file):
     assert "Error converting" in caplog.text
 
 
-def test_dir_to_csv_no_continue(tmp_path, sas7bdat_dir, bad_sas_file):
+def test_dir_to_csv_continue_xpt(tmp_path, caplog, xpt_dir, bad_xpt_file):
+    xpt_files = [str(x) for x in xpt_dir.iterdir()]
+    for sas_file in xpt_files:
+        shutil.copy(sas_file, str(tmp_path))
+
+    shutil.copy(bad_xpt_file, str(tmp_path))
+
+    sas7bdat_converter.dir_to_csv(tmp_path, continue_on_error=True)
+    sas_counter = len([name for name in tmp_path.iterdir() if name.suffix == ".xpt"]) - 1
+    convert_counter = len([name for name in tmp_path.iterdir() if name.suffix == ".csv"])
+
+    assert sas_counter == convert_counter
+    assert "Error converting" in caplog.text
+
+
+def test_dir_to_csv_no_continue_sas(tmp_path, sas7bdat_dir, bad_sas_file):
     sas_files = [str(x) for x in sas7bdat_dir.iterdir()]
     for sas_file in sas_files:
         shutil.copy(sas_file, str(tmp_path))
@@ -572,7 +1059,19 @@ def test_dir_to_csv_no_continue(tmp_path, sas7bdat_dir, bad_sas_file):
     assert execinfo.value
 
 
-def test_dir_to_csv_different_dir_path(tmp_path, sas7bdat_dir):
+def test_dir_to_csv_no_continue_xpt(tmp_path, xpt_dir, bad_xpt_file):
+    sas_files = [str(x) for x in xpt_dir.iterdir()]
+    for sas_file in sas_files:
+        shutil.copy(sas_file, str(tmp_path))
+
+    shutil.copy(bad_xpt_file, str(tmp_path))
+    with pytest.raises(Exception) as execinfo:
+        sas7bdat_converter.dir_to_csv(tmp_path, continue_on_error=False)
+
+    assert execinfo.value
+
+
+def test_dir_to_csv_different_dir_path_sas(tmp_path, sas7bdat_dir):
     sas7bdat_converter.dir_to_csv(dir_path=sas7bdat_dir, export_path=tmp_path)
     sas_counter = len([name for name in sas7bdat_dir.iterdir() if name.suffix == ".sas7bdat"])
     convert_counter = len([name for name in tmp_path.iterdir() if name.suffix == ".csv"])
@@ -580,7 +1079,15 @@ def test_dir_to_csv_different_dir_path(tmp_path, sas7bdat_dir):
     assert sas_counter == convert_counter
 
 
-def test_dir_to_csv_different_dir_str(tmpdir, sas7bdat_dir):
+def test_dir_to_csv_different_dir_path_xpt(tmp_path, xpt_dir):
+    sas7bdat_converter.dir_to_csv(dir_path=xpt_dir, export_path=tmp_path)
+    xpt_counter = len([name for name in xpt_dir.iterdir() if name.suffix == ".xpt"])
+    convert_counter = len([name for name in tmp_path.iterdir() if name.suffix == ".csv"])
+
+    assert xpt_counter == convert_counter
+
+
+def test_dir_to_csv_different_dir_str_sas(tmpdir, sas7bdat_dir):
     sas7bdat_converter.dir_to_csv(dir_path=str(sas7bdat_dir), export_path=tmpdir)
     sas_counter = len([name for name in Path(sas7bdat_dir).iterdir() if name.suffix == ".sas7bdat"])
     convert_counter = len([name for name in Path(tmpdir).iterdir() if name.suffix == ".csv"])
@@ -588,7 +1095,15 @@ def test_dir_to_csv_different_dir_str(tmpdir, sas7bdat_dir):
     assert sas_counter == convert_counter
 
 
-def test_dir_to_excel_same_dir_path(tmp_path, sas7bdat_dir):
+def test_dir_to_csv_different_dir_str_xpt(tmpdir, xpt_dir):
+    sas7bdat_converter.dir_to_csv(dir_path=str(xpt_dir), export_path=tmpdir)
+    xpt_counter = len([name for name in Path(xpt_dir).iterdir() if name.suffix == ".xpt"])
+    convert_counter = len([name for name in Path(tmpdir).iterdir() if name.suffix == ".csv"])
+
+    assert xpt_counter == convert_counter
+
+
+def test_dir_to_excel_same_dir_path_sas(tmp_path, sas7bdat_dir):
     sas_files = [x for x in sas7bdat_dir.iterdir()]
     for sas_file in sas_files:
         shutil.copy(sas_file, str(tmp_path))
@@ -600,7 +1115,19 @@ def test_dir_to_excel_same_dir_path(tmp_path, sas7bdat_dir):
     assert sas_counter == convert_counter
 
 
-def test_dir_to_excel_same_dir_str(tmpdir, sas7bdat_dir):
+def test_dir_to_excel_same_dir_path_xpt(tmp_path, xpt_dir):
+    xpt_files = [x for x in xpt_dir.iterdir()]
+    for xpt_file in xpt_files:
+        shutil.copy(xpt_file, str(tmp_path))
+
+    sas7bdat_converter.dir_to_excel(tmp_path)
+    xpt_counter = len([name for name in tmp_path.iterdir() if name.suffix == ".xpt"])
+    convert_counter = len([name for name in tmp_path.iterdir() if name.suffix == ".xlsx"])
+
+    assert xpt_counter == convert_counter
+
+
+def test_dir_to_excel_same_dir_str_sas(tmpdir, sas7bdat_dir):
     sas_files = [str(x) for x in sas7bdat_dir.iterdir()]
     for sas_file in sas_files:
         shutil.copy(sas_file, tmpdir)
@@ -612,7 +1139,19 @@ def test_dir_to_excel_same_dir_str(tmpdir, sas7bdat_dir):
     assert sas_counter == convert_counter
 
 
-def test_dir_to_excel_different_dir_path(tmp_path, sas7bdat_dir):
+def test_dir_to_excel_same_dir_str_xpt(tmpdir, xpt_dir):
+    xpt_files = [str(x) for x in xpt_dir.iterdir()]
+    for xpt_file in xpt_files:
+        shutil.copy(xpt_file, tmpdir)
+
+    sas7bdat_converter.dir_to_excel(tmpdir)
+    xpt_counter = len([name for name in Path(tmpdir).iterdir() if name.suffix == ".xpt"])
+    convert_counter = len([name for name in Path(tmpdir).iterdir() if name.suffix == ".xlsx"])
+
+    assert xpt_counter == convert_counter
+
+
+def test_dir_to_excel_different_dir_path_sas(tmp_path, sas7bdat_dir):
     sas7bdat_converter.dir_to_excel(dir_path=sas7bdat_dir, export_path=tmp_path)
     sas_counter = len([name for name in sas7bdat_dir.iterdir() if name.suffix == ".sas7bdat"])
     convert_counter = len([name for name in tmp_path.iterdir() if name.suffix == ".xlsx"])
@@ -620,7 +1159,15 @@ def test_dir_to_excel_different_dir_path(tmp_path, sas7bdat_dir):
     assert sas_counter == convert_counter
 
 
-def test_dir_to_excel_different_dir_str(tmpdir, sas7bdat_dir):
+def test_dir_to_excel_different_dir_path_xpt(tmp_path, xpt_dir):
+    sas7bdat_converter.dir_to_excel(dir_path=xpt_dir, export_path=tmp_path)
+    xpt_counter = len([name for name in xpt_dir.iterdir() if name.suffix == ".xpt"])
+    convert_counter = len([name for name in tmp_path.iterdir() if name.suffix == ".xlsx"])
+
+    assert xpt_counter == convert_counter
+
+
+def test_dir_to_excel_different_dir_str_sas(tmpdir, sas7bdat_dir):
     sas7bdat_converter.dir_to_excel(dir_path=str(sas7bdat_dir), export_path=tmpdir)
     sas_counter = len([name for name in Path(sas7bdat_dir).iterdir() if name.suffix == ".sas7bdat"])
     convert_counter = len([name for name in Path(tmpdir).iterdir() if name.suffix == ".xlsx"])
@@ -628,7 +1175,15 @@ def test_dir_to_excel_different_dir_str(tmpdir, sas7bdat_dir):
     assert sas_counter == convert_counter
 
 
-def test_dir_to_excel_continue(tmp_path, caplog, sas7bdat_dir, bad_sas_file):
+def test_dir_to_excel_different_dir_str_xpt(tmpdir, xpt_dir):
+    sas7bdat_converter.dir_to_excel(dir_path=str(xpt_dir), export_path=tmpdir)
+    xpt_counter = len([name for name in Path(xpt_dir).iterdir() if name.suffix == ".xpt"])
+    convert_counter = len([name for name in Path(tmpdir).iterdir() if name.suffix == ".xlsx"])
+
+    assert xpt_counter == convert_counter
+
+
+def test_dir_to_excel_continue_sas(tmp_path, caplog, sas7bdat_dir, bad_sas_file):
     sas_files = [str(x) for x in sas7bdat_dir.iterdir()]
     for sas_file in sas_files:
         shutil.copy(sas_file, str(tmp_path))
@@ -643,7 +1198,22 @@ def test_dir_to_excel_continue(tmp_path, caplog, sas7bdat_dir, bad_sas_file):
     assert "Error converting" in caplog.text
 
 
-def test_dir_to_excel_no_continue(tmp_path, sas7bdat_dir, bad_sas_file):
+def test_dir_to_excel_continue_xpt(tmp_path, caplog, xpt_dir, bad_xpt_file):
+    xpt_files = [str(x) for x in xpt_dir.iterdir()]
+    for xpt_file in xpt_files:
+        shutil.copy(xpt_file, str(tmp_path))
+
+    shutil.copy(bad_xpt_file, str(tmp_path))
+
+    sas7bdat_converter.dir_to_excel(tmp_path, continue_on_error=True)
+    xpt_counter = len([name for name in tmp_path.iterdir() if name.suffix == ".xpt"]) - 1
+    convert_counter = len([name for name in tmp_path.iterdir() if name.suffix == ".xlsx"])
+
+    assert xpt_counter == convert_counter
+    assert "Error converting" in caplog.text
+
+
+def test_dir_to_excel_no_continue_sas(tmp_path, sas7bdat_dir, bad_sas_file):
     sas_files = [str(x) for x in sas7bdat_dir.iterdir()]
     for sas_file in sas_files:
         shutil.copy(sas_file, str(tmp_path))
@@ -655,7 +1225,19 @@ def test_dir_to_excel_no_continue(tmp_path, sas7bdat_dir, bad_sas_file):
     assert execinfo.value
 
 
-def test_dir_to_json_same_dir_path(tmp_path, sas7bdat_dir):
+def test_dir_to_excel_no_continue_xpt(tmp_path, xpt_dir, bad_xpt_file):
+    xpt_files = [str(x) for x in xpt_dir.iterdir()]
+    for xpt_file in xpt_files:
+        shutil.copy(xpt_file, str(tmp_path))
+
+    shutil.copy(bad_xpt_file, str(tmp_path))
+    with pytest.raises(Exception) as execinfo:
+        sas7bdat_converter.dir_to_excel(tmp_path, continue_on_error=False)
+
+    assert execinfo.value
+
+
+def test_dir_to_json_same_dir_path_sas(tmp_path, sas7bdat_dir):
     sas_files = [x for x in sas7bdat_dir.iterdir()]
     for sas_file in sas_files:
         shutil.copy(sas_file, tmp_path)
@@ -667,7 +1249,19 @@ def test_dir_to_json_same_dir_path(tmp_path, sas7bdat_dir):
     assert sas_counter == convert_counter
 
 
-def test_dir_to_json_same_dir_str(tmpdir, sas7bdat_dir):
+def test_dir_to_json_same_dir_path_xpt(tmp_path, xpt_dir):
+    xpt_files = [x for x in xpt_dir.iterdir()]
+    for xpt_file in xpt_files:
+        shutil.copy(xpt_file, tmp_path)
+
+    sas7bdat_converter.dir_to_json(tmp_path)
+    xpt_counter = len([name for name in tmp_path.iterdir() if name.suffix == ".xpt"])
+    convert_counter = len([name for name in tmp_path.iterdir() if name.suffix == ".json"])
+
+    assert xpt_counter == convert_counter
+
+
+def test_dir_to_json_same_dir_str_sas(tmpdir, sas7bdat_dir):
     sas_files = [str(x) for x in sas7bdat_dir.iterdir()]
     for sas_file in sas_files:
         shutil.copy(sas_file, tmpdir)
@@ -679,7 +1273,19 @@ def test_dir_to_json_same_dir_str(tmpdir, sas7bdat_dir):
     assert sas_counter == convert_counter
 
 
-def test_dir_to_json_different_dir_path(tmp_path, sas7bdat_dir):
+def test_dir_to_json_same_dir_str_xpt(tmpdir, xpt_dir):
+    xpt_files = [str(x) for x in xpt_dir.iterdir()]
+    for xpt_file in xpt_files:
+        shutil.copy(xpt_file, tmpdir)
+
+    sas7bdat_converter.dir_to_json(tmpdir)
+    xpt_counter = len([name for name in Path(tmpdir).iterdir() if name.suffix == ".xpt"])
+    convert_counter = len([name for name in Path(tmpdir).iterdir() if name.suffix == ".json"])
+
+    assert xpt_counter == convert_counter
+
+
+def test_dir_to_json_different_dir_path_sas(tmp_path, sas7bdat_dir):
     sas7bdat_converter.dir_to_json(sas7bdat_dir, tmp_path)
     sas_counter = len([name for name in sas7bdat_dir.iterdir() if name.suffix == ".sas7bdat"])
     convert_counter = len([name for name in tmp_path.iterdir() if name.suffix == ".json"])
@@ -687,7 +1293,15 @@ def test_dir_to_json_different_dir_path(tmp_path, sas7bdat_dir):
     assert sas_counter == convert_counter
 
 
-def test_dir_to_json_different_dir_str(tmpdir, sas7bdat_dir):
+def test_dir_to_json_different_dir_path_xpt(tmp_path, xpt_dir):
+    sas7bdat_converter.dir_to_json(xpt_dir, tmp_path)
+    xpt_counter = len([name for name in xpt_dir.iterdir() if name.suffix == ".xpt"])
+    convert_counter = len([name for name in tmp_path.iterdir() if name.suffix == ".json"])
+
+    assert xpt_counter == convert_counter
+
+
+def test_dir_to_json_different_dir_str_sas(tmpdir, sas7bdat_dir):
     sas7bdat_converter.dir_to_json(str(sas7bdat_dir), tmpdir)
     sas_counter = len([name for name in Path(sas7bdat_dir).iterdir() if name.suffix == ".sas7bdat"])
     convert_counter = len([name for name in Path(tmpdir).iterdir() if name.suffix == ".json"])
@@ -695,7 +1309,15 @@ def test_dir_to_json_different_dir_str(tmpdir, sas7bdat_dir):
     assert sas_counter == convert_counter
 
 
-def test_dir_to_json_continue(tmp_path, caplog, sas7bdat_dir, bad_sas_file):
+def test_dir_to_json_different_dir_str_xpt(tmpdir, xpt_dir):
+    sas7bdat_converter.dir_to_json(str(xpt_dir), tmpdir)
+    xpt_counter = len([name for name in Path(xpt_dir).iterdir() if name.suffix == ".xpt"])
+    convert_counter = len([name for name in Path(tmpdir).iterdir() if name.suffix == ".json"])
+
+    assert xpt_counter == convert_counter
+
+
+def test_dir_to_json_continue_sas(tmp_path, caplog, sas7bdat_dir, bad_sas_file):
     sas_files = [str(x) for x in sas7bdat_dir.iterdir()]
     for sas_file in sas_files:
         shutil.copy(sas_file, str(tmp_path))
@@ -710,7 +1332,22 @@ def test_dir_to_json_continue(tmp_path, caplog, sas7bdat_dir, bad_sas_file):
     assert "Error converting" in caplog.text
 
 
-def test_dir_to_json_no_continue(tmp_path, sas7bdat_dir, bad_sas_file):
+def test_dir_to_json_continue_xpt(tmp_path, caplog, xpt_dir, bad_xpt_file):
+    xpt_files = [str(x) for x in xpt_dir.iterdir()]
+    for xpt_file in xpt_files:
+        shutil.copy(xpt_file, str(tmp_path))
+
+    shutil.copy(bad_xpt_file, str(tmp_path))
+
+    sas7bdat_converter.dir_to_json(tmp_path, continue_on_error=True)
+    xpt_counter = len([name for name in tmp_path.iterdir() if name.suffix == ".xpt"]) - 1
+    convert_counter = len([name for name in tmp_path.iterdir() if name.suffix == ".json"])
+
+    assert xpt_counter == convert_counter
+    assert "Error converting" in caplog.text
+
+
+def test_dir_to_json_no_continue_sas(tmp_path, sas7bdat_dir, bad_sas_file):
     sas_files = [str(x) for x in sas7bdat_dir.iterdir()]
     for sas_file in sas_files:
         shutil.copy(sas_file, str(tmp_path))
@@ -722,7 +1359,19 @@ def test_dir_to_json_no_continue(tmp_path, sas7bdat_dir, bad_sas_file):
     assert execinfo.value
 
 
-def test_dir_to_xml_same_dir_path(tmp_path, sas7bdat_dir):
+def test_dir_to_json_no_continue_xpt(tmp_path, xpt_dir, bad_xpt_file):
+    xpt_files = [str(x) for x in xpt_dir.iterdir()]
+    for xpt_file in xpt_files:
+        shutil.copy(xpt_file, str(tmp_path))
+
+    shutil.copy(bad_xpt_file, str(tmp_path))
+    with pytest.raises(Exception) as execinfo:
+        sas7bdat_converter.dir_to_json(tmp_path, continue_on_error=False)
+
+    assert execinfo.value
+
+
+def test_dir_to_xml_same_dir_path_sas(tmp_path, sas7bdat_dir):
     sas_files = [x for x in sas7bdat_dir.iterdir()]
     for sas_file in sas_files:
         shutil.copy(sas_file, str(tmp_path))
@@ -734,7 +1383,19 @@ def test_dir_to_xml_same_dir_path(tmp_path, sas7bdat_dir):
     assert sas_counter == convert_counter
 
 
-def test_dir_to_xml_same_dir_str(tmpdir, sas7bdat_dir):
+def test_dir_to_xml_same_dir_path_xpt(tmp_path, xpt_dir):
+    xpt_files = [x for x in xpt_dir.iterdir()]
+    for xpt_file in xpt_files:
+        shutil.copy(xpt_file, str(tmp_path))
+
+    sas7bdat_converter.dir_to_xml(tmp_path)
+    xpt_counter = len([name for name in tmp_path.iterdir() if name.suffix == ".xpt"])
+    convert_counter = len([name for name in tmp_path.iterdir() if name.suffix == ".xml"])
+
+    assert xpt_counter == convert_counter
+
+
+def test_dir_to_xml_same_dir_str_sas(tmpdir, sas7bdat_dir):
     sas_files = [str(x) for x in sas7bdat_dir.iterdir()]
     for sas_file in sas_files:
         shutil.copy(sas_file, tmpdir)
@@ -746,7 +1407,19 @@ def test_dir_to_xml_same_dir_str(tmpdir, sas7bdat_dir):
     assert sas_counter == convert_counter
 
 
-def test_dir_to_xml_different_dir_path(tmp_path, sas7bdat_dir):
+def test_dir_to_xml_same_dir_str_xpt(tmpdir, xpt_dir):
+    xpt_files = [str(x) for x in xpt_dir.iterdir()]
+    for xpt_file in xpt_files:
+        shutil.copy(xpt_file, tmpdir)
+
+    sas7bdat_converter.dir_to_xml(tmpdir)
+    xpt_counter = len([name for name in Path(tmpdir).iterdir() if name.suffix == ".xpt"])
+    convert_counter = len([name for name in Path(tmpdir).iterdir() if name.suffix == ".xml"])
+
+    assert xpt_counter == convert_counter
+
+
+def test_dir_to_xml_different_dir_path_sas(tmp_path, sas7bdat_dir):
     sas7bdat_converter.dir_to_xml(sas7bdat_dir, tmp_path)
     sas_counter = len([name for name in sas7bdat_dir.iterdir() if name.suffix == ".sas7bdat"])
     convert_counter = len([name for name in tmp_path.iterdir() if name.suffix == ".xml"])
@@ -754,7 +1427,15 @@ def test_dir_to_xml_different_dir_path(tmp_path, sas7bdat_dir):
     assert sas_counter == convert_counter
 
 
-def test_dir_to_xml_different_dir_str(tmpdir, sas7bdat_dir):
+def test_dir_to_xml_different_dir_path_xpt(tmp_path, xpt_dir):
+    sas7bdat_converter.dir_to_xml(xpt_dir, tmp_path)
+    xpt_counter = len([name for name in xpt_dir.iterdir() if name.suffix == ".xpt"])
+    convert_counter = len([name for name in tmp_path.iterdir() if name.suffix == ".xml"])
+
+    assert xpt_counter == convert_counter
+
+
+def test_dir_to_xml_different_dir_str_sas(tmpdir, sas7bdat_dir):
     sas7bdat_converter.dir_to_xml(str(sas7bdat_dir), tmpdir)
     sas_counter = len([name for name in Path(sas7bdat_dir).iterdir() if name.suffix == ".sas7bdat"])
     convert_counter = len([name for name in Path(tmpdir).iterdir() if name.suffix == ".xml"])
@@ -762,7 +1443,15 @@ def test_dir_to_xml_different_dir_str(tmpdir, sas7bdat_dir):
     assert sas_counter == convert_counter
 
 
-def test_dir_to_xml_continue(tmp_path, caplog, sas7bdat_dir, bad_sas_file):
+def test_dir_to_xml_different_dir_str_xpt(tmpdir, xpt_dir):
+    sas7bdat_converter.dir_to_xml(str(xpt_dir), tmpdir)
+    xpt_counter = len([name for name in Path(xpt_dir).iterdir() if name.suffix == ".xpt"])
+    convert_counter = len([name for name in Path(tmpdir).iterdir() if name.suffix == ".xml"])
+
+    assert xpt_counter == convert_counter
+
+
+def test_dir_to_xml_continue_sas(tmp_path, caplog, sas7bdat_dir, bad_sas_file):
     sas_files = [str(x) for x in sas7bdat_dir.iterdir()]
     for sas_file in sas_files:
         shutil.copy(sas_file, str(tmp_path))
@@ -777,7 +1466,22 @@ def test_dir_to_xml_continue(tmp_path, caplog, sas7bdat_dir, bad_sas_file):
     assert "Error converting" in caplog.text
 
 
-def test_dir_to_xml_no_continue(tmp_path, sas7bdat_dir, bad_sas_file):
+def test_dir_to_xml_continue_xpt(tmp_path, caplog, xpt_dir, bad_xpt_file):
+    xpt_files = [str(x) for x in xpt_dir.iterdir()]
+    for xpt_file in xpt_files:
+        shutil.copy(xpt_file, str(tmp_path))
+
+    shutil.copy(bad_xpt_file, str(tmp_path))
+
+    sas7bdat_converter.dir_to_xml(tmp_path, continue_on_error=True)
+    xpt_counter = len([name for name in tmp_path.iterdir() if name.suffix == ".xpt"]) - 1
+    convert_counter = len([name for name in tmp_path.iterdir() if name.suffix == ".xml"])
+
+    assert xpt_counter == convert_counter
+    assert "Error converting" in caplog.text
+
+
+def test_dir_to_xml_no_continue_sas(tmp_path, sas7bdat_dir, bad_sas_file):
     sas_files = [str(x) for x in sas7bdat_dir.iterdir()]
     for sas_file in sas_files:
         shutil.copy(sas_file, str(tmp_path))
@@ -789,6 +1493,18 @@ def test_dir_to_xml_no_continue(tmp_path, sas7bdat_dir, bad_sas_file):
     assert execinfo.value
 
 
+def test_dir_to_xml_no_continue_xpt(tmp_path, xpt_dir, bad_xpt_file):
+    xpt_files = [str(x) for x in xpt_dir.iterdir()]
+    for xpt_file in xpt_files:
+        shutil.copy(xpt_file, str(tmp_path))
+
+    shutil.copy(bad_xpt_file, str(tmp_path))
+    with pytest.raises(Exception) as execinfo:
+        sas7bdat_converter.dir_to_xml(tmp_path, continue_on_error=False)
+
+    assert execinfo.value
+
+
 exception_data = [
     (
         "sas7bdat conversion error - Valid extension for to_csv conversion is: .csv",
@@ -870,7 +1586,7 @@ def test_is_valid_extension_true(data):
 
 
 @pytest.fixture(params=["sas_file_1", "sas_file_2", "sas_file_3"])
-def test_to_csv_path(tmp_path, request, expected_dir):
+def test_to_csv_path_sas(tmp_path, request, expected_dir):
     sas_file = Path(request.getfixturevalue(request.param))
     converted_file = tmp_path.joinpath("file1.csv")
     expected_file = expected_dir.joinpath("file1.csv")
@@ -879,8 +1595,18 @@ def test_to_csv_path(tmp_path, request, expected_dir):
     assert filecmp.cmp(converted_file, expected_file, shallow=False)
 
 
+@pytest.fixture(params=["xpt_file_1", "xpt_file_2"])
+def test_to_csv_path_xpt(tmp_path, request, xpt_expected_dir):
+    xpt_file = Path(request.getfixturevalue(request.param))
+    converted_file = tmp_path.joinpath("file1.csv")
+    expected_file = xpt_expected_dir.joinpath("file1.csv")
+    converter.to_csv(xpt_file, converted_file)
+
+    assert filecmp.cmp(converted_file, expected_file, shallow=False)
+
+
 @pytest.fixture(params=["sas_file_1", "sas_file_2", "sas_file_3"])
-def test_to_csv_str(tmpdir, request, expected_dir):
+def test_to_csv_str_sas(tmpdir, request, expected_dir):
     sas_file = request.getfixturevalue(request.param)
     converted_file = str(Path(tmpdir).joinpath("file1.csv"))
     expected_file = expected_dir.joinpath("file1.csv")
@@ -889,6 +1615,16 @@ def test_to_csv_str(tmpdir, request, expected_dir):
     assert filecmp.cmp(converted_file, expected_file, shallow=False)
 
 
+@pytest.fixture(params=["xpt_file_1", "xpt_file_2"])
+def test_to_csv_str_xpt(tmpdir, request, xpt_expected_dir):
+    sas_file = request.getfixturevalue(request.param)
+    converted_file = str(Path(tmpdir).joinpath("file1.csv"))
+    expected_file = xpt_expected_dir.joinpath("file1.csv")
+    sas7bdat_converter.to_csv(sas_file, converted_file)
+
+    assert filecmp.cmp(converted_file, expected_file, shallow=False)
+
+
 def test_to_csv_invalid_extension():
     with pytest.raises(AttributeError) as execinfo:
         sas7bdat_converter.to_csv("test.sas7bdat", "test.bad")
@@ -896,7 +1632,7 @@ def test_to_csv_invalid_extension():
     assert "sas7bdat conversion error - Valid extension" in str(execinfo.value)
 
 
-def test_to_dataframe(sas_file_1):
+def test_to_dataframe_sas(sas_file_1):
     d = {
         "integer_row": [
             1.0,
@@ -935,8 +1671,29 @@ def test_to_dataframe(sas_file_1):
     pd.testing.assert_frame_equal(df, df_file, check_datetimelike_compat=True)
 
 
+def test_to_dataframe_xpt(xpt_file_1):
+    d = {
+        "irow": [
+            1.0,
+            2.0,
+        ],
+        "trow": [
+            "Some text",
+            "Some more test",
+        ],
+        "frow": [
+            1.50,
+            17.23,
+        ],
+    }
+
+    df = pd.DataFrame(data=d)
+    df_file = converter.to_dataframe(xpt_file_1)
+    pd.testing.assert_frame_equal(df, df_file)
+
+
 @pytest.fixture(params=["sas_file_1", "sas_file_2", "sas_file_3"])
-def test_to_excel_path(tmp_path, request, expected_dir):
+def test_to_excel_path_sas(tmp_path, request, expected_dir):
     sas_file = Path(request.getfixturevalue(request.param))
     converted_file = tmp_path.joinpath("file1.xlsx")
     expected_file = expected_dir.joinpath("file1.xlsx")
@@ -948,8 +1705,21 @@ def test_to_excel_path(tmp_path, request, expected_dir):
     pd.testing.assert_frame_equal(df_expected, df_converted)
 
 
+@pytest.fixture(params=["xpt_file_1", "xpt_file_2"])
+def test_to_excel_path_xpt(tmp_path, request, xpt_expected_dir):
+    xpt_file = Path(request.getfixturevalue(request.param))
+    converted_file = tmp_path.joinpath("file1.xlsx")
+    expected_file = xpt_expected_dir.joinpath("file1.xlsx")
+    sas7bdat_converter.to_excel(xpt_file, converted_file)
+
+    df_expected = pd.read_excel(expected_file, engine="openpyxl")
+    df_converted = pd.read_excel(converted_file, engine="openpyxl")
+
+    pd.testing.assert_frame_equal(df_expected, df_converted)
+
+
 @pytest.fixture(params=["sas_file_1", "sas_file_2", "sas_file_3"])
-def test_to_excel_str(tmpdir, request, expected_dir):
+def test_to_excel_str_sas(tmpdir, request, expected_dir):
     sas_file = request.getfixturevalue(request.param)
     converted_file = str(Path(tmpdir).joinpath("file1.xlsx"))
     expected_file = expected_dir.joinpath("file1.xlsx")
@@ -961,6 +1731,19 @@ def test_to_excel_str(tmpdir, request, expected_dir):
     pd.testing.assert_frame_equal(df_expected, df_converted)
 
 
+@pytest.fixture(params=["xpt_file_1", "xpt_file_2"])
+def test_to_excel_str_xpt(tmpdir, request, xpt_expected_dir):
+    xpt_file = request.getfixturevalue(request.param)
+    converted_file = str(Path(tmpdir).joinpath("file1.xlsx"))
+    expected_file = xpt_expected_dir.joinpath("file1.xlsx")
+    sas7bdat_converter.to_excel(xpt_file, converted_file)
+
+    df_expected = pd.read_excel(expected_file, engine="openpyxl")
+    df_converted = pd.read_excel(converted_file, engine="openpyxl")
+
+    pd.testing.assert_frame_equal(df_expected, df_converted)
+
+
 def test_to_excel_invalid_extension():
     with pytest.raises(AttributeError) as execinfo:
         sas7bdat_converter.to_excel("test.sas7bdat", "test.bad")
@@ -969,7 +1752,7 @@ def test_to_excel_invalid_extension():
 
 
 @pytest.fixture(params=["sas_file_1", "sas_file_2", "sas_file_3"])
-def test_to_json_path(tmp_path, request, expected_dir):
+def test_to_json_path_sas(tmp_path, request, expected_dir):
     sas_file = Path(request.getfixturevalue(request.param))
     converted_file = tmp_path.joinpath("file1.json")
     expected_file = expected_dir.joinpath("file1.json")
@@ -978,8 +1761,18 @@ def test_to_json_path(tmp_path, request, expected_dir):
     assert filecmp.cmp(converted_file, expected_file, shallow=False)
 
 
+@pytest.fixture(params=["xpt_file_1", "xpt_file_2"])
+def test_to_json_path_xpt(tmp_path, request, xpt_expected_dir):
+    xpt_file = Path(request.getfixturevalue(request.param))
+    converted_file = tmp_path.joinpath("file1.json")
+    expected_file = xpt_expected_dir.joinpath("file1.json")
+    sas7bdat_converter.to_json(xpt_file, converted_file)
+
+    assert filecmp.cmp(converted_file, expected_file, shallow=False)
+
+
 @pytest.fixture(params=["sas_file_1", "sas_file_2", "sas_file_3"])
-def test_to_json_str(tmpdir, request, expected_dir):
+def test_to_json_str_sas(tmpdir, request, expected_dir):
     sas_file = request.getfixturevalue(request.param)
     converted_file = str(Path(tmpdir).joinpath("file1.json"))
     expected_file = expected_dir.joinpath("file1.json")
@@ -988,6 +1781,16 @@ def test_to_json_str(tmpdir, request, expected_dir):
     assert filecmp.cmp(converted_file, expected_file, shallow=False)
 
 
+@pytest.fixture(params=["xpt_file_1", "xpt_file_2"])
+def test_to_json_str_xpt(tmpdir, request, xpt_expected_dir):
+    xpt_file = request.getfixturevalue(request.param)
+    converted_file = str(Path(tmpdir).joinpath("file1.json"))
+    expected_file = xpt_expected_dir.joinpath("file1.json")
+    sas7bdat_converter.to_json(xpt_file, converted_file)
+
+    assert filecmp.cmp(converted_file, expected_file, shallow=False)
+
+
 def test_to_json_invalid_extension():
     with pytest.raises(AttributeError) as execinfo:
         sas7bdat_converter.to_json("test.sas7bdat", "test.bad")
@@ -996,7 +1799,7 @@ def test_to_json_invalid_extension():
 
 
 @pytest.fixture(params=["sas_file_1", "sas_file_2", "sas_file_3"])
-def test_to_xml_path(tmp_path, request, expected_dir):
+def test_to_xml_path_sas(tmp_path, request, expected_dir):
     sas_file = Path(request.getfixturevalue(request.param))
     converted_file = tmp_path.joinpath("file1.xml")
     expected_file = expected_dir.joinpath("file1.xml")
@@ -1005,8 +1808,18 @@ def test_to_xml_path(tmp_path, request, expected_dir):
     assert filecmp.cmp(converted_file, expected_file, shallow=False)
 
 
+@pytest.fixture(params=["xpt_file_1", "xpt_file_2"])
+def test_to_xml_path_xpt(tmp_path, request, xpt_expected_dir):
+    xpt_file = Path(request.getfixturevalue(request.param))
+    converted_file = tmp_path.joinpath("file1.xml")
+    expected_file = xpt_expected_dir.joinpath("file1.xml")
+    sas7bdat_converter.to_xml(xpt_file, converted_file)
+
+    assert filecmp.cmp(converted_file, expected_file, shallow=False)
+
+
 @pytest.fixture(params=["sas_file_1", "sas_file_2", "sas_file_3"])
-def test_to_xml_str(tmpdir, request, expected_dir):
+def test_to_xml_str_sas(tmpdir, request, expected_dir):
     sas_file = request.getfixturevalue(request.param)
     converted_file = str(Path(tmpdir).joinpath("file1.xml"))
     expected_file = expected_dir.joinpath("file1.xml")
@@ -1015,6 +1828,16 @@ def test_to_xml_str(tmpdir, request, expected_dir):
     assert filecmp.cmp(converted_file, expected_file, shallow=False)
 
 
+@pytest.fixture(params=["xpt_file_1", "xpt_file_2"])
+def test_to_xml_str_xpt(tmpdir, request, xpt_expected_dir):
+    xpt_file = request.getfixturevalue(request.param)
+    converted_file = str(Path(tmpdir).joinpath("file1.xml"))
+    expected_file = xpt_expected_dir.joinpath("file1.xml")
+    sas7bdat_converter.to_xml(xpt_file, converted_file)
+
+    assert filecmp.cmp(converted_file, expected_file, shallow=False)
+
+
 def test_to_xml_invalid_extension():
     with pytest.raises(AttributeError) as execinfo:
         sas7bdat_converter.to_xml("test.sas7bdat", "test.bad")
@@ -1067,7 +1890,7 @@ def test_format_path(path):
 
 
 @pytest.mark.parametrize("file_type", ["csv", "xlsx", "json", "xml"])
-def test_walk_dir(tmpdir, sas7bdat_dir, file_type):
+def test_walk_dir_sas(tmpdir, sas7bdat_dir, file_type):
     sas_files = [str(x) for x in sas7bdat_dir.iterdir()]
     for sas_file in sas_files:
         shutil.copy(sas_file, tmpdir)
@@ -1079,3 +1902,18 @@ def test_walk_dir(tmpdir, sas7bdat_dir, file_type):
     )
 
     assert sas_counter == convert_counter
+
+
+@pytest.mark.parametrize("file_type", ["csv", "xlsx", "json", "xml"])
+def test_walk_dir_xpt(tmpdir, xpt_dir, file_type):
+    xpt_files = [str(x) for x in xpt_dir.iterdir()]
+    for xpt_file in xpt_files:
+        shutil.copy(xpt_file, tmpdir)
+
+    converter._walk_dir(file_type, tmpdir, False)
+    xpt_counter = len([name for name in Path(tmpdir).iterdir() if name.suffix == ".xpt"])
+    convert_counter = len(
+        [name for name in Path(tmpdir).iterdir() if name.suffix == f".{file_type}"]
+    )
+
+    assert xpt_counter == convert_counter