diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index bc0df40fcd50d8bd173ca9307fab0c095706e669..4d36a6fdcbb688da878d07e95fc71e8277d82aa4 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -14,14 +14,14 @@ build-job:       # This job runs in the build stage, which runs first.
     - pip install -r requirements_dev.txt
     - pip install .
 
-# unit-test-job:   # This job runs in the test stage.
-#   stage: test    # It only starts when the job in the build stage completes successfully.
-#   script:
-#     - pip install -r requirements.txt
-#     - pip install -r requirements_dev.txt
-#     - pip install .
-#     - coverage run --source primingsitepredictor -m pytest
-#     - coverage report -m
+unit-test-job:   # This job runs in the test stage.
+  stage: test    # It only starts when the job in the build stage completes successfully.
+  script:
+    - pip install -r requirements.txt
+    - pip install -r requirements_dev.txt
+    - pip install .
+    - coverage run --source primingsitepredictor -m pytest
+    - coverage report -m
 
 lint-test-job:   # This job also runs in the test stage.
   stage: test    # It can run at the same time as unit-test-job (in parallel).
@@ -29,6 +29,6 @@ lint-test-job:   # This job also runs in the test stage.
     - pip install -r requirements.txt
     - pip install -r requirements_dev.txt
     - pip install .
-    - flake8 --docstring-convention google primingsitepredictor/ # tests/
-    - pylint primingsitepredictor/ # tests/
+    - flake8 --docstring-convention google primingsitepredictor/
+    - pylint primingsitepredictor/
     - mypy primingsitepredictor/
diff --git a/README.md b/README.md
index c9f0307bdaa5dde8f5140f8f5f6a2487e9b6d7a3..484ae490a8bb65bd910e683ead36d9c56f6e0821 100644
--- a/README.md
+++ b/README.md
@@ -6,10 +6,7 @@ Priming Site Predictor which uses a seed-and-extension algorithm (*RIblast*: htt
 ## Version
 Version 0.1.0 (2022/11/15)
 
-## Acknowledgements
-We used the RIblast algorithm created by Tsukasa Fukunaga (https://github.com/fukunagatsu). 
-
-## Installation from github 
+## Installation from GitLab
 Priming Site Predictor requires Python 3.9 or later.
 
 Install Priming Site Predictor from GitLab using:
@@ -17,7 +14,11 @@ Install Priming Site Predictor from GitLab using:
 ```
 git clone https://git.scicore.unibas.ch/zavolan_group/tools/priming-site-predictor.git
 cd priming-site-predictor
-pip install . 
+```
+Create scRNA-seq-simulation conda environment:
+```
+conda env create --file environment.yml
+conda activate scrna-seq-sim
 ```
 
 ## Usage
@@ -54,5 +55,8 @@ This software is released under the MIT License, see LICENSE.txt.
 ## Contributors
 Max Bär, Sophie Schnider, Robin Christen (University of Basel)
 
+## Acknowledgements
+We used the RIblast algorithm created by Tsukasa Fukunaga (https://github.com/fukunagatsu). 
+
 ## Reference
 Tsukasa Fukunaga and Michiaki Hamada. "RIblast: An ultrafast RNA-RNA interaction prediction system based on a seed-and-extension approach." btx287, Bioinformatics (2017)
diff --git a/primingsitepredictor/__init__.py b/primingsitepredictor/__init__.py
index 66eb5ba958a8629efed8cbd53b8801505a0c219f..bb7d5f3186cb2e516714c06c9a5e8d2b57696586 100644
--- a/primingsitepredictor/__init__.py
+++ b/primingsitepredictor/__init__.py
@@ -1 +1 @@
-"""Initialize package."""
+"""Initialise package."""
diff --git a/primingsitepredictor/cli.py b/primingsitepredictor/cli.py
index 3f5c9f791454ba8e0b82d5363460bfe24f92b67a..530cab497ca0b519780cc7aa536cb00dcafa623d 100644
--- a/primingsitepredictor/cli.py
+++ b/primingsitepredictor/cli.py
@@ -1,8 +1,8 @@
 """Receive command line arguments."""
 import argparse
 import logging
-from primingsitepredictor.prime_site_predictor import CreatePrimer
-from primingsitepredictor.prime_site_predictor import PrimingSitePredictor
+from primingsitepredictor.psp import CreatePrimer
+from primingsitepredictor.psp import PrimingSitePredictor
 
 LOG = logging.getLogger(__name__)
 
@@ -34,8 +34,8 @@ def setup_logging() -> None:
         verbosity: Level of logging verbosity.
     """
     logging.basicConfig(
-        format='[%(asctime)s: %(levelname)s] %(message)s \
-            (module "%(module)s")',
+        format='[%(asctime)s: %(levelname)s] %(message)s '
+               '(module "%(module)s")',
         level=logging.INFO,
     )
 
@@ -72,44 +72,3 @@ def parse_args():
 
 if __name__ == "__main__":
     main()
-
-
-# def main():
-#     """Execute generate_RIBlast."""
-#     generate_riblast_input()
-
-
-# def generate_riblast_input():
-#     """Create a list of the filenames for the RIBlast."""
-#     my_primer = CreatePrimer()
-#     my_primer.create_fasta()
-#     primer_filename = my_primer.name + ".fasta"
-#     transcripts_filename = "transcripts.fasta"
-
-#     return [primer_filename, transcripts_filename]
-
-
-# def create_gtf():
-#     """Create gtf."""
-#     gtf_file = PostProcessRIBlast().output
-#     print(gtf_file)
-
-
-# def create_parser():
-#     """Create a parser."""
-#     parser = argparse.ArgumentParser(
-#         prog='PrimingSitePredictor',
-#         description='Takes a cutoff energy and the predicts \
-#             location of priming sites of transcripts',
-#         epilog='To predict or not to predict')
-#     parser.add_argument('--float', type=float, required=True,
-#                         help='An energy-cutoff float number')
-#     parsed_args = parser.parse_args()
-#     energy_cutoff = parsed_args.float
-#     return energy_cutoff
-
-
-# def letsgo():
-#     """Create a parser and print the energycutoff."""
-#     energy_cutoff = create_parser()
-#     print(f"Your energy cutoff is {energy_cutoff}")
diff --git a/primingsitepredictor/prime_site_predictor.py b/primingsitepredictor/psp.py
similarity index 85%
rename from primingsitepredictor/prime_site_predictor.py
rename to primingsitepredictor/psp.py
index bbc3cd31e1ca2ab7eeb7e05e23beb94658b7acc0..9c92cd18ef928d79ffdf2314183cae536c66dffa 100644
--- a/primingsitepredictor/prime_site_predictor.py
+++ b/primingsitepredictor/psp.py
@@ -1,6 +1,7 @@
 """Main module for Priming Site Predictor."""
 import math
 import logging
+import re
 import pandas as pd  # type: ignore
 
 LOG = logging.getLogger(__name__)
@@ -8,10 +9,10 @@ LOG = logging.getLogger(__name__)
 
 # pylint: disable=R0903
 class CreatePrimer:
-    """Create an instance of a primer of a desired length \
-        and primer name which can be saved as a fasta file.
+    """Create an instance of a primer of a desired length and name.
 
-    By default the length is 15 and name is primer.
+    The primer is saved as a fasta file.
+    By default, the length is 15 and the name is "primer".
     """
 
     def __init__(self, name='primer', primerlength=15):
@@ -60,10 +61,12 @@ class PrimingSitePredictor:
             raw_interactions = file.readlines()[firstline:]
         number_entries = len(raw_interactions)
 
-        for i in range(0, number_entries-1):
-            current_interaction = raw_interactions[i].strip(
-                ' \n').replace('(', '').replace(')', '').replace(
-                '-', ',').replace(':', ',').split(',')
+        for i in range(0, number_entries):
+            pattern = r'(?<=[0-9])-(?=[0-9])'
+            current_interaction = re.sub(pattern, ',', raw_interactions[i])
+            current_interaction = current_interaction.strip(
+                ' \n').replace('(', '').replace(
+                    ')', '').replace(':', ',').split(',')
             interaction_list.append(current_interaction)
 
         return interaction_list
diff --git a/tests/__init__.py b/tests/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..0cf13d23e76271f02a81a28e53018db6ed382f49
--- /dev/null
+++ b/tests/__init__.py
@@ -0,0 +1 @@
+"""Initialise testing."""
diff --git a/tests/test_cli.py b/tests/test_cli.py
index 94676a8ba6d32fe5a501c921fc0b80f45730377c..624f47493939f9396c84dc405ced4beca25c7f52 100644
--- a/tests/test_cli.py
+++ b/tests/test_cli.py
@@ -2,6 +2,7 @@
 import unittest
 from unittest.mock import patch
 from primingsitepredictor import cli
+from primingsitepredictor.cli import setup_logging
 
 
 class TestCli(unittest.TestCase):
@@ -75,3 +76,11 @@ class TestCli(unittest.TestCase):
                 ]):
             with self.assertRaises(SystemExit):
                 cli.parse_args()
+
+
+class TestSetupLogging:
+    """Test ``setup_logging()`` function."""
+
+    def test_log_level_default(self):
+        """Call without args."""
+        setup_logging()
diff --git a/tests/test_createprimer.py b/tests/test_createprimer.py
deleted file mode 100644
index 94e15043299e883f9858ee7e3f30c78883eddc91..0000000000000000000000000000000000000000
--- a/tests/test_createprimer.py
+++ /dev/null
@@ -1,55 +0,0 @@
-"""Tests for createprimer.py."""
-import unittest
-from unittest.mock import patch, mock_open
-import pytest
-from primingsitepredictor.prime_site_predictor import CreatePrimer
-
-
-class TestCreatePrimer(unittest.TestCase):
-    """Test CreatePrimer function."""
-
-    def test_init(self):
-        """Test the  __init__() default values."""
-        primer = CreatePrimer()
-        self.assertEqual(primer.name, 'primer')
-        self.assertEqual(primer.primer_length, 15)
-        self.assertEqual(primer.primer_sequence, 'T'*15)
-        self.assertEqual(primer.lines, ['<primer', 'TTTTTTTTTTTTTTT'])
-        with pytest.raises(TypeError):
-            CreatePrimer(type(int), type(str))
-
-    def test_init_custom(self):
-        """Test the  __init__() custom values."""
-        primer = CreatePrimer('my_primer', 20)
-        self.assertEqual(primer.name, 'my_primer')
-        self.assertEqual(primer.primer_length, 20)
-        self.assertEqual(primer.primer_sequence, 'T'*20)
-        self.assertEqual(primer.lines, ['<my_primer', 'TTTTTTTTTTTTTTTTTTTT'])
-
-    def test_create_fasta(self):
-        """Test the test_create_fasta default values."""
-        with patch('builtins.open', new_callable=mock_open) as mock_file:
-            primer = CreatePrimer()
-            primer.create_fasta()
-
-            # assert if opened file on write mode 'w'
-            mock_file.assert_called_once_with(
-                'primer.fasta', 'w', encoding='utf-8'
-            )
-            # assert if the specific content was written in file
-            expected_content = '<primer\nTTTTTTTTTTTTTTT'
-            mock_file().write.assert_called_once_with(expected_content)
-
-    def test_create_fasta_custom(self):
-        """Test the test_create_fasta custom values."""
-        with patch('builtins.open', new_callable=mock_open) as mock_file:
-            primer = CreatePrimer('my_primer', 20)
-            primer.create_fasta()
-
-            # assert if opened file on write mode 'w'
-            mock_file.assert_called_once_with(
-                'my_primer.fasta', 'w', encoding='utf-8'
-            )
-            # assert if the specific content was written in file
-            expected_content = '<my_primer\nTTTTTTTTTTTTTTTTTTTT'
-            mock_file().write.assert_called_once_with(expected_content)
diff --git a/tests/test_main.py b/tests/test_main.py
deleted file mode 100644
index d57812ddb70b516bd672b74e486ad1cb176d3f92..0000000000000000000000000000000000000000
--- a/tests/test_main.py
+++ /dev/null
@@ -1,94 +0,0 @@
-"""
-Created on Tue Dec 20 14:06:20 2022
-
-@author: RobinC
-"""
-
-# Imports
-import os
-import sys
-currentdir = os.path.dirname(os.path.realpath(__file__))
-parentdir = os.path.dirname(currentdir)
-sys.path.append(parentdir)
-import unittest
-import main as mn
-import createprimer as cp
-import postprocessing as pp
-from io import StringIO
-
-class TestMain(unittest.TestCase):
-
-    def test_import(self):
-        """Test function for module imports"""
-        try:
-            import CreatePrimer
-        except ImportError:
-            self.fail("Failed to import CreatePrimer")
-
-        try:
-            import PostProcessRIBlast
-        except ImportError:
-            self.fail("Failed to import PostProcessRIBlast")
-
-    def test_generate_riblast_input(self):
-        """Test funciton for the method generate_riblast_input()"""
-
-        # Call the CreatePrimer() method and the create_fasta() method
-        primer = cp.CreatePrimer()
-        primer.create_fasta()
-
-        # get the name and the transcript filename
-        primer_filename = primer.name+".fasta"
-        transcript_filename = "transcripts.fasta"
-
-        # Call the generate_riblast_input() method
-        result = mn.generate_riblast_input()
-
-        assert result == [primer_filename, transcript_filename]
-
-
-    def test_create_gtf(self):
-        """Test funciton for the method create_gtf()"""
-
-        # Call the output of the PostprocessRIBlast() method
-        result = pp.PostProcessRIBlast().output
-
-        # Open the expected output
-        with open('output_transcripts_df.txt', 'r') as f:
-            expected_output = f.read()
-
-        # Use an assertion to check the output result
-        assert result == expected_output
-
-        # Capture the output of the print statement
-        captured_output = StringIO()
-        sys.stdout = captured_output
-
-        # Call the function that contains the print statement
-        mn.create_gtf()
-
-        # Check the captured output against the expected value
-        assert captured_output.getvalue().strip() == expected_output
-
-
-    def test_main(self):
-        """Test function for the method main()"""
-
-        # Call the CreatePrimer() method and the create_fasta() method
-        primer = cp.CreatePrimer()
-        primer.create_fasta()
-
-        # get the name and the transcript filename
-        primer_filename = primer.name+".fasta"
-        transcripts_filename = "transcripts.fasta"
-
-        # Get the results for the called methods
-        result1 = mn.generate_riblast_input()
-        result2 = mn.create_gtf()
-
-        # Open the expected output
-        with open('output_transcripts_df.txt', 'r') as f:
-            expected_output = f.read()
-
-        assert result1 == [primer_filename, transcripts_filename]
-        assert result2 == expected_output
diff --git a/tests/test_postprocessing.py b/tests/test_postprocessing.py
deleted file mode 100644
index 0132906fe1f4cf2e7efd59376be904e3f68129b7..0000000000000000000000000000000000000000
--- a/tests/test_postprocessing.py
+++ /dev/null
@@ -1,213 +0,0 @@
-
-import unittest
-from unittest import mock
-import math
-from primingsitepredictor.prime_site_predictor import PrimingSitePredictor
-
-
-class TestPrimingSitePredictor(unittest.TestCase):
-    """Test PrimingSitePredictor."""
-
-    def setUp(self):
-        """Create an instance of PrimingSitePredictor."""
-        # You need to provide the required parameters to the constructor
-        self.post_processor = PrimingSitePredictor(
-            fasta_file="test.fasta",
-            primer_sequence="T" * 15,
-            energy_cutoff=0.5,
-            riblast_output="test_files/RIBlast_output_example.txt",
-            output_filename="test_output.gtf"
-        )
-
-    def test_generate_gtf(self):
-        """Test the generate_gtf() method."""
-        # Create a mock DataFrame to be returned by create_pandas_df()
-        mock_df = mock.MagicMock()
-        mock_df.index = [0]
-        mock_df[3][0] = 'Transcript_1'
-        mock_df[13][0] = '(0-14:2988-2974)'
-        mock_df[12][0] = '+'
-        mock_df["Normalised_interaction_energy"][0] = 0.75
-
-        with mock.patch.object(
-            self.post_processor, "create_pandas_df", return_value=mock_df
-        ):
-            expected_output = (
-                'Transcript_1\tRIBlast\tPriming_site\t(0-14:2988-2974)\t+\t.\t+\t.\tInteraction_Energy\t0.75\n'
-            )
-            print(self.post_processor.generate_gtf())
-            print(expected_output)
-            # self.assertEqual(self.post_processor.generate_gtf(), expected_output)
-
-    def test_calculate_energy(self):
-        """Test the calculate_energy() method."""
-        test_instance = self.post_processor
-        decimal_place = 20
-
-        # Test for a positive value
-        self.assertAlmostEqual(
-            test_instance.calculate_energy(9.76),
-            math.exp(-9.76 * 6.9477 * 10 ** -21 / (1.380649e-23 * 298)),
-            decimal_place
-        )
-
-        # Test for a negative value
-        self.assertAlmostEqual(
-            test_instance.calculate_energy(-5.0),
-            math.exp(5.0 * 6.9477 * 10 ** -21 / (1.380649e-23 * 298)),
-            decimal_place
-        )
-
-        # Test for zero
-        self.assertAlmostEqual(
-            test_instance.calculate_energy(0),
-            math.exp(0 * 6.9477 * 10 ** -21 / (1.380649e-23 * 298)),
-            decimal_place
-        )
-
-    def test_create_list_from_output(self):
-        """Test the create_list_from_output() method."""
-        # Mocking the file readlines method
-        mock_readlines = mock.MagicMock()
-        mock_readlines.return_value = [
-            "header1\n",
-            "header2\n",
-            "header3\n",
-            "0,Test_Primer,15,Transcript_1,3233,1.49191,-9.76,-8.26809,(0-14:2988-2974)\n",
-            "1,Test_Primer,15,Transcript_1,3233,1.02308,-9.76,-8.73692,(0-14:18-4)\n",
-        ]
-
-        with mock.patch("builtins.open", mock.mock_open(read_data="")) as m, \
-                mock.patch.object(
-                    m.return_value, "readlines", mock_readlines
-                ):
-            expected_output = [
-                ['0', 'Test_Primer', '15', 'Transcript_1', '3233', '1.49191', '-9.76', '-8.26809', '(0-14:2988-2974)'],
-                ['1', 'Test_Primer', '15', 'Transcript_1', '3233', '1.02308', '-9.76', '-8.73692', '(0-14:18-4)']
-            ]
-            self.assertEqual(self.post_processor.create_list_from_output(), expected_output)
-
-
-if __name__ == "__main__":
-    unittest.main()
-
-# class TestPrimingSitePredictor(unittest.TestCase):
-#     """Test PrimingSitePredictor."""
-
-#     def setUp(self):
-#         """Setup function to create an instance of PrimingSitePredictor."""
-#         self.post_processor = PrimingSitePredictor()
-
-#     def test_init(self):
-#         """Test the __init__() method."""
-#         # Test if generate_gtf method is being called
-#         with unittest.mock.patch.object(
-#             PrimingSitePredictor, "generate_gtf"
-#         ) as mock_generate_gtf:
-#             PrimingSitePredictor()
-#             mock_generate_gtf.assert_called_once()
-
-#         # Test if generate_gtf returns the expected output
-#         expected_output = (
-#             'Transcript_1\tRIBlast\tPriming_site\t2974[3257 chars]3"\n'
-#         )
-#         self.assertEqual(self.post_processor.generate_gtf(), expected_output)
-
-#     def test_calculate_energy(self):
-#         """Test the calculate_energy() method."""
-
-#         def calculate_energy(value):
-#             energy_constant = 1.380649*10**(-23)*298
-#             kcalmol_joul = 6.9477*10**-21
-#             return (math.exp(-float(value)*kcalmol_joul/energy_constant))
-
-#         # set a decimal place
-#         decimalPlace = 20
-
-#         # Test for a positive value
-#         self.testinstance = pp.PostProcessRIBlast.calculate_energy(self, 5.0)
-#         expected_output = calculate_energy(5.0)
-#         self.assertAlmostEqual(self.testinstance, expected_output, decimalPlace)
-
-
-#         # Test for a negative value
-#         self.testinstance = pp.PostProcessRIBlast.calculate_energy(self, -5.0)
-#         expected_output = calculate_energy(-5.0)
-#         self.assertAlmostEqual(self.testinstance, expected_output, decimalPlace)
-
-#         # Test for zero
-#         self.testinstance = pp.PostProcessRIBlast.calculate_energy(self, 0)
-#         expected_output = calculate_energy(0)
-#         self.assertAlmostEqual(self.testinstance, expected_output, decimalPlace)
-
-#     def test_create_list_from_output(self):
-#         """Test the create_list_from_output() method."""
-#         # create an instance test of the class PostProcessRIBlast()
-#         test = pp.PostProcessRIBlast()
-#         test.file = "RIBlast output example.txt"
-
-#         with open('RIBlast output example.txt', 'r', encoding="utf-8") as file:
-#             data_list = file.readlines()
-
-#         # Remove the header
-#         data_list = data_list[3:]
-
-#         # Convert each row of the list into a list of values
-#         expected_output = []
-#         for row in data_list:
-#             # Split the row by the comma character
-#             values = row.strip().split(',')
-#             # Append the list of values to the final list
-#             expected_output.append(values)
-#         return expected_output
-#         self.assertEqual(test.create_list_from_output(), expected_output)
-
-#     def test_create_pandas_df(self):
-#         """Test the create_pandas_df() method with mock data."""
-#         # create a test instance
-#         test_instance = pp.PostProcessRIBlast()
-
-#         # create some mock data for the input list
-#         test_instance.interaction_list = [
-#                                 ['Id', 'Query name', 'Query Length', 'Target name', 'Target Length', 'Accessibility Energy', 'Hybridization Energy', 'Interaction Energy', 'BasePair'],
-#                                 [0, 'Test_Primer', 15, 'Transcript_1', 3233, 1.49191, -9.76, -8.26809, '(0-14:2988-2974)'],
-#                                 [1, 'Test_Primer', 15, 'Transcript_1', 3233, 1.02308, -9.76, -8.73692, '(0-14:18-4)'],
-#                                 [2, 'Test_Primer', 15, 'Transcript_1', 3233, 0.947439, -9.73, -8.78256, '(0-14:17-3)'],
-#                                 [3, 'Test_Primer', 15, 'Transcript_1', 3233, 0.793049, -9.73, -8.93695, '(0-14:16-2)'],
-#                                 [4, 'Test_Primer', 15, 'Transcript_1', 3233, 0.483869, -9.73, -9.24613, '(0-14:15-1)'],
-#                                 [5, 'Test_Primer', 15, 'Transcript_1', 3233, 0.441093, -9.17, -8.72891, '(0-14:14-0)']]
-
-#         # create the DataFrame using the mock data
-#         df = test_instance.create_pandas_df()
-
-#         #self.assertEqual(len(df),7)
-
-#         # check that the DataFrame has the expected column names
-#         #self.assertEqual(list(df.columns), ['Id','Query name', 'Query Length', 'Target name', 'Target Length', 'Accessibility Energy', 'Hybridization Energy', 'Interaction Energy', 'BasePair'])
-
-#         # check that the values in the 'Id' column are correct
-#         self.assertEqual(list(df['Id']), ['Id',0,1,2,3,4,5])
-
-#         # check that the values in the 'Query name' column are correct
-#         self.assertEqual(list(df['Query name']), ['Query name','Test_Primer','Test_Primer','Test_Primer','Test_Primer','Test_Primer','Test_Primer'])
-
-#         # check that the values in the 'Query Length' column are correct
-#         self.assertEqual(list(df['Query Length']), ['Query Length',15, 15, 15, 15, 15, 15])
-
-#         # check that the values in the 'Target name' column are correct
-#         self.assertEqual(list(df['Target name']), ['Target name','Transcript_1','Transcript_1','Transcript_1','Transcript_1','Transcript_1','Transcript_1'])
-
-#         # check that the values in the 'Target Length' column are correct
-#         self.assertEqual(list(df['Target Length']), ['Target Length', 3233, 3233, 3233, 3233, 3233, 3233])
-
-#         # check that the values in the 'Accessibility Energy' column are correct
-#         self.assertEqual(list(df['Accessibility Energy']), ['Accessibility Energy',1.49191, 1.02308, 0.947439, 0.793049, 0.483869, 0.441093])
-
-#         # check that the values in the 'Hybridization Energy' column are correct
-#         self.assertEqual(list(df['Hybridization Energy']), ['Hybridization Energy',-9.76, -9.76, -9.73, -9.73, -9.73, -9.17])
-
-#         # check that the values in the 'Interaction Energy' column are correct
-#         self.assertEqual(list(df['Interaction Energy']), ['Interaction Energy',-8.26809, -8.73692, -8.78256, -8.93695, -9.24613, -8.72891])
-
-#         # check that the values in the 'BasePair' column are correct
-#         self.assertEqual(list(df['BasePair']), ['BasePair','(0-14:2988-2974)', '(0-14:18-4)', '(0-14:17-3)', '(0-14:16-2)', '(0-14:15-1)', '(0-14:14-0)'])
diff --git a/tests/test_psp.py b/tests/test_psp.py
new file mode 100644
index 0000000000000000000000000000000000000000..988a2e2f5bf4b99c0012aad7365aed3d4657865a
--- /dev/null
+++ b/tests/test_psp.py
@@ -0,0 +1,166 @@
+"""Tests for createprimer.py."""
+import unittest
+from unittest.mock import patch, mock_open
+from unittest import mock
+import math
+import pandas as pd  # type: ignore
+import pytest
+from primingsitepredictor.psp import CreatePrimer
+from primingsitepredictor.psp import PrimingSitePredictor
+
+
+class TestCreatePrimer(unittest.TestCase):
+    """Test CreatePrimer function."""
+
+    def test_init(self):
+        """Test the  __init__() default values."""
+        primer = CreatePrimer()
+        self.assertEqual(primer.name, 'primer')
+        self.assertEqual(primer.primer_length, 15)
+        self.assertEqual(primer.primer_sequence, 'T'*15)
+        self.assertEqual(primer.lines, ['<primer', 'TTTTTTTTTTTTTTT'])
+        with pytest.raises(TypeError):
+            CreatePrimer(type(int), type(str))
+
+    def test_init_custom(self):
+        """Test the  __init__() custom values."""
+        primer = CreatePrimer('my_primer', 20)
+        self.assertEqual(primer.name, 'my_primer')
+        self.assertEqual(primer.primer_length, 20)
+        self.assertEqual(primer.primer_sequence, 'T'*20)
+        self.assertEqual(primer.lines, ['<my_primer', 'TTTTTTTTTTTTTTTTTTTT'])
+
+    def test_create_fasta(self):
+        """Test the test_create_fasta default values."""
+        with patch('builtins.open', new_callable=mock_open) as mock_file:
+            primer = CreatePrimer()
+            primer.create_fasta()
+
+            # assert if opened file on write mode 'w'
+            mock_file.assert_called_once_with(
+                'primer.fasta', 'w', encoding='utf-8'
+            )
+            # assert if the specific content was written in file
+            expected_content = '<primer\nTTTTTTTTTTTTTTT'
+            mock_file().write.assert_called_once_with(expected_content)
+
+    def test_create_fasta_custom(self):
+        """Test the test_create_fasta custom values."""
+        with patch('builtins.open', new_callable=mock_open) as mock_file:
+            primer = CreatePrimer('my_primer', 20)
+            primer.create_fasta()
+
+            # assert if opened file on write mode 'w'
+            mock_file.assert_called_once_with(
+                'my_primer.fasta', 'w', encoding='utf-8'
+            )
+            # assert if the specific content was written in file
+            expected_content = '<my_primer\nTTTTTTTTTTTTTTTTTTTT'
+            mock_file().write.assert_called_once_with(expected_content)
+
+
+class TestPrimingSitePredictor(unittest.TestCase):
+    """Test PrimingSitePredictor."""
+
+    def setUp(self):
+        """Create an instance of PrimingSitePredictor."""
+        # You need to provide the required parameters to the constructor
+        self.post_processor = PrimingSitePredictor(
+            fasta_file="test.fasta",
+            primer_sequence="T" * 15,
+            energy_cutoff=0.5,
+            riblast_output="test_files/RIBlast_output_example.txt",
+            output_filename="test_output.gtf"
+        )
+
+    def test_generate_gtf(self):
+        """Test the generate_gtf() method."""
+        # Create a mock DataFrame to be returned by create_pandas_df()
+        mock_df = mock.MagicMock()
+        mock_df.index = [0]
+        mock_df[3][0] = 'Transcript_1'
+        mock_df[13][0] = '(0-14:2988-2974)'
+        mock_df[12][0] = '+'
+        mock_df["Normalised_interaction_energy"][0] = 0.75
+
+        with mock.patch.object(
+            self.post_processor, "create_pandas_df", return_value=mock_df
+        ):
+            expected_output = (
+                'Transcript_1\tRIBlast\tPriming_site\t(0-14:2988-2974)\t'
+                '+\t.\t+\t.\tInteraction_Energy\t0.75\n'
+            )
+            print(self.post_processor.generate_gtf())
+            print(expected_output)
+            # self.assertEqual(self.post_processor.generate_gtf(),
+            # expected_output)
+
+    def test_calculate_energy(self):
+        """Test the calculate_energy() method."""
+        test_instance = self.post_processor
+        decimal_place = 20
+
+        # Test for a positive value
+        self.assertAlmostEqual(
+            test_instance.calculate_energy(9.76),
+            math.exp(-9.76 * 6.9477 * 10 ** -21 / (1.380649e-23 * 298)),
+            decimal_place
+        )
+
+        # Test for a negative value
+        self.assertAlmostEqual(
+            test_instance.calculate_energy(-5.0),
+            math.exp(5.0 * 6.9477 * 10 ** -21 / (1.380649e-23 * 298)),
+            decimal_place
+        )
+
+        # Test for zero
+        self.assertAlmostEqual(
+            test_instance.calculate_energy(0),
+            math.exp(0 * 6.9477 * 10 ** -21 / (1.380649e-23 * 298)),
+            decimal_place
+        )
+
+    def test_create_list_from_output(self):
+        """Test the create_list_from_output() method."""
+        # Mocking the file readlines method
+        mock_readlines = mock.MagicMock()
+        mock_readlines.return_value = [
+            "header1\n",
+            "header2\n",
+            "header3\n",
+            "0,Test_Primer,15,Transcript_1,3233,"
+            "1.49191,-9.76,-8.26809,(0-14:2988-2974)\n",
+            "1,Test_Primer,15,Transcript_1,3233,"
+            "1.02308,-9.76,-8.73692,(0-14:18-4)\n",
+        ]
+
+        with mock.patch("builtins.open", mock.mock_open(read_data="")) as m, \
+            mock.patch.object(
+                m.return_value, "readlines", mock_readlines
+                ):
+            expected_output = [
+                ['0', 'Test_Primer', '15', 'Transcript_1', '3233',
+                    '1.49191', '-9.76', '-8.26809', '0', '14', '2988', '2974'],
+                ['1', 'Test_Primer', '15', 'Transcript_1', '3233',
+                    '1.02308', '-9.76', '-8.73692', '0', '14', '18', '4']
+            ]
+            self.assertEqual(
+                self.post_processor.create_list_from_output(), expected_output
+            )
+
+    def test_create_pandas_df(self):
+        """Test the create_pandas_df() method."""
+        # Mock the create_list_from_output method
+        with mock.patch.object(
+            self.post_processor, 'create_list_from_output', return_value=[
+                ['0', 'Test_Primer', '15', 'Transcript_1', '3233',
+                 '1.49191', '-9.76', '-8.26809', '0', '14', '2988', '2974'],
+                ['1', 'Test_Primer', '15', 'Transcript_1', '3233',
+                 '1.02308', '-9.76', '-8.73692', '0', '14', '18', '4']
+                ]):
+            result = self.post_processor.create_pandas_df()
+
+        # Perform your assertions on the result DataFrame
+        self.assertIsInstance(result, pd.DataFrame)
+        self.assertEqual(len(result), 2)