diff --git a/ippisite/ippidb/tests.py b/ippisite/ippidb/tests.py
index cd0914b0c3702b189c47be16f79bc76c9ea6e616..2c2d02a6d01dd840c602d6b62c201f2761ca1865 100644
--- a/ippisite/ippidb/tests.py
+++ b/ippisite/ippidb/tests.py
@@ -8,7 +8,6 @@ from django.contrib.auth import get_user_model
 from django.core.management import call_command
 from django.test import TestCase
 from django.urls import reverse
-from openbabel import vectorUnsignedInt, OBFingerprint
 import requests
 
 
@@ -26,7 +25,6 @@ from .models import (
     PcaBiplotData,
 )
 from .models import DrugBankCompound, Protein
-from .utils import FingerPrinter, mol2smi, smi2mol, smi2inchi, smi2inchikey, smi2sdf
 
 
 class MolSmiTestCase(TestCase):
@@ -44,12 +42,6 @@ class MolSmiTestCase(TestCase):
             " 0  0  0  0  0  0  0  0\nM  END\n"
         )
 
-    def test_mol2smi(self):
-        self.assertEqual(mol2smi(self.mol), self.smiles)
-
-    def test_smi2mol2smi(self):
-        self.assertTrue(re.compile(self.mol).match(smi2mol(self.smiles)))
-
     def test_view_smi2mol_valid(self):
         url = reverse("smi2mol")
         response = self.client.get(url, {"smiString": self.smiles})
@@ -89,94 +81,6 @@ class MolSmiTestCase(TestCase):
         self.assertEqual(response.status_code, 400)
 
 
-class SmiInchi(TestCase):
-    """
-    Test INCHI and INCHIKEY generation functions
-    """
-
-    def setUp(self):
-        self.smiles_str = (
-            "CC(C)C(=O)C1=C(C(=C(C(=C1)C(=O)C2=CC=C(C=C2)" "OC3=CC=CC=C3)O)O)O"
-        )
-        self.inchi_str = (
-            "InChI=1S/C23H20O6/c1-13(2)19(24)17-12-18(22"
-            "(27)23(28)21(17)26)20(25)14-8-10-16(11-9-14)29-15-6-4-3-"
-            "5-7-15/h3-13,26-28H,1-2H3"
-        )
-        self.inchikey_str = "CVVQMBDTMYUWTR-UHFFFAOYSA-N"
-
-    def test_smi2inchi(self):
-        self.assertEqual(smi2inchi(self.smiles_str), self.inchi_str)
-
-    def test_smi2inchikey(self):
-        self.assertEqual(smi2inchikey(self.smiles_str), self.inchikey_str)
-
-
-class FingerPrinterTestCase(TestCase):
-    """
-    Test FingerPrinter class
-    """
-
-    def setUp(self):
-        self.fingerprinter = FingerPrinter("FP4")
-        self.smiles = "CC"
-        self.fp = vectorUnsignedInt([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
-        self.smiles_dict = {1: "CC", 2: "CCC"}
-        self.fp_dict = {
-            1: vectorUnsignedInt([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),
-            2: vectorUnsignedInt([3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),
-        }
-        self.tanimoto_dict = {1: 1.0, 2: 0.5}
-
-    def test_fingerprints_available(self):
-        # test that all necessary fingerprints are available
-        self.assertIsNotNone(OBFingerprint.FindFingerprint("FP2"))
-        self.assertIsNotNone(OBFingerprint.FindFingerprint("FP4"))
-        self.assertIsNotNone(OBFingerprint.FindFingerprint("ECFP4"))
-
-    def assertEqualVUI(self, vui_one, vui_two):
-        return self.assertEqual(list(vui_one), list(vui_two))
-
-    def assertEqualVUIdict(self, vuidict_one, vuidict_two):
-        vuidict_one = {id_: list(vui) for id_, vui in vuidict_one.items()}
-        vuidict_two = {id_: list(vui) for id_, vui in vuidict_two.items()}
-        return self.assertEqual(vuidict_one, vuidict_two)
-
-    def test_fp(self):
-        self.assertEqualVUI(self.fingerprinter.fp(self.smiles), self.fp)
-
-    def test_fp_dict(self):
-        self.assertEqualVUIdict(
-            self.fingerprinter.fp_dict(self.smiles_dict), self.fp_dict
-        )
-
-    def test_tanimoto_fps(self):
-        self.assertEqual(
-            self.fingerprinter.tanimoto_fps(self.smiles, self.fp_dict),
-            self.tanimoto_dict,
-        )
-
-    def test_tanimoto_smiles(self):
-        self.assertEqual(
-            self.fingerprinter.tanimoto_smiles(self.smiles, self.smiles_dict),
-            self.tanimoto_dict,
-        )
-
-
-class FingerPrinterTestCaseCompound1ECFP4(TestCase):
-    def setUp(self):
-        self.fingerprinter = FingerPrinter("ECFP4")
-        self.smiles = "CC(C)C(=O)c1cc(C(=O)c2ccc(Oc3ccccc3)cc2)c(O)c(O)c1O"
-        self.smiles_dict = {1: "CC(C)C(=O)c1cc(C(=O)c2ccc(Oc3ccccc3)cc2)c(O)" "c(O)c1O"}
-        self.tanimoto_dict = {1: 1.0}
-
-    def test_tanimoto_smiles(self):
-        self.assertEqual(
-            self.fingerprinter.tanimoto_smiles(self.smiles, self.smiles_dict),
-            self.tanimoto_dict,
-        )
-
-
 def create_dummy_compound(id_, smiles):
     c = Compound()
     c.id = id_
@@ -918,30 +822,6 @@ class TestConvertSMILESToIUPAC(TestCase):
             )
 
 
-class TestConvertSMILESToSDF(TestCase):
-    """
-    Test converting a smiles to SDF using openbabel
-    """
-
-    def test_valid(self):
-        smiles_to_sdfs = {
-            "C": [
-                "1",
-                " OpenBabel04142011372D",
-                "",
-                "  1  0  0  0  0  0  0  0  0  0999 V2000",
-                "    0.0000    0.0000    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0",
-                "M  END",
-                "$$$$",
-            ]
-        }
-        for smiles, expected_lines in smiles_to_sdfs.items():
-            result = smi2sdf({1: smiles})
-            result_lines = result.split("\n")
-            for line_idx in [0, 2, 3, 4, 5, 6]:
-                self.assertEqual(result_lines[line_idx], expected_lines[line_idx])
-
-
 class DuplicateGeneNameTestCase(TestCase):
     def test_works(self):
         models.Protein.objects.get_or_create(uniprot_id="P12497")
diff --git a/ippisite/ippidb/tests_utils.py b/ippisite/ippidb/tests_utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..0865028b482683279168d132f32822a20bc645c6
--- /dev/null
+++ b/ippisite/ippidb/tests_utils.py
@@ -0,0 +1,143 @@
+"""
+iPPI-DB unit tests
+"""
+import re
+
+from django.test import TestCase
+from openbabel import vectorUnsignedInt, OBFingerprint
+
+from .utils import FingerPrinter, mol2smi, smi2mol, smi2inchi, smi2inchikey, smi2sdf
+
+
+class MolSmiTestCase(TestCase):
+    """
+    Test MOL to SMILES and SMILES to MOL format conversion functions
+    """
+
+    def setUp(self):
+        self.smiles = "C"
+        # the MOL version is also a valid regexp to validate arbitrary name in
+        # the openbabel-generated version
+        self.mol = (
+            "\n OpenBabel[0-9]{11}D\n\n  1  0  0  0  0  0  0  0 "
+            " 0  0999 V2000\n    1.0000    0.0000    0.0000 C   0  0  0  0 "
+            " 0  0  0  0  0  0  0  0\nM  END\n"
+        )
+
+    def test_mol2smi(self):
+        self.assertEqual(mol2smi(self.mol), self.smiles)
+
+    def test_smi2mol2smi(self):
+        self.assertTrue(re.compile(self.mol).match(smi2mol(self.smiles)))
+
+
+class SmiInchiTestCase(TestCase):
+    """
+    Test INCHI and INCHIKEY generation functions
+    """
+
+    def setUp(self):
+        self.smiles_str = (
+            "CC(C)C(=O)C1=C(C(=C(C(=C1)C(=O)C2=CC=C(C=C2)" "OC3=CC=CC=C3)O)O)O"
+        )
+        self.inchi_str = (
+            "InChI=1S/C23H20O6/c1-13(2)19(24)17-12-18(22"
+            "(27)23(28)21(17)26)20(25)14-8-10-16(11-9-14)29-15-6-4-3-"
+            "5-7-15/h3-13,26-28H,1-2H3"
+        )
+        self.inchikey_str = "CVVQMBDTMYUWTR-UHFFFAOYSA-N"
+
+    def test_smi2inchi(self):
+        self.assertEqual(smi2inchi(self.smiles_str), self.inchi_str)
+
+    def test_smi2inchikey(self):
+        self.assertEqual(smi2inchikey(self.smiles_str), self.inchikey_str)
+
+
+class FingerPrinterTestCase(TestCase):
+    """
+    Test FingerPrinter class
+    """
+
+    def setUp(self):
+        self.fingerprinter = FingerPrinter("FP4")
+        self.smiles = "CC"
+        self.fp = vectorUnsignedInt([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
+        self.smiles_dict = {1: "CC", 2: "CCC"}
+        self.fp_dict = {
+            1: vectorUnsignedInt([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),
+            2: vectorUnsignedInt([3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]),
+        }
+        self.tanimoto_dict = {1: 1.0, 2: 0.5}
+
+    def test_fingerprints_available(self):
+        # test that all necessary fingerprints are available
+        self.assertIsNotNone(OBFingerprint.FindFingerprint("FP2"))
+        self.assertIsNotNone(OBFingerprint.FindFingerprint("FP4"))
+        self.assertIsNotNone(OBFingerprint.FindFingerprint("ECFP4"))
+
+    def assertEqualVUI(self, vui_one, vui_two):
+        return self.assertEqual(list(vui_one), list(vui_two))
+
+    def assertEqualVUIdict(self, vuidict_one, vuidict_two):
+        vuidict_one = {id_: list(vui) for id_, vui in vuidict_one.items()}
+        vuidict_two = {id_: list(vui) for id_, vui in vuidict_two.items()}
+        return self.assertEqual(vuidict_one, vuidict_two)
+
+    def test_fp(self):
+        self.assertEqualVUI(self.fingerprinter.fp(self.smiles), self.fp)
+
+    def test_fp_dict(self):
+        self.assertEqualVUIdict(
+            self.fingerprinter.fp_dict(self.smiles_dict), self.fp_dict
+        )
+
+    def test_tanimoto_fps(self):
+        self.assertEqual(
+            self.fingerprinter.tanimoto_fps(self.smiles, self.fp_dict),
+            self.tanimoto_dict,
+        )
+
+    def test_tanimoto_smiles(self):
+        self.assertEqual(
+            self.fingerprinter.tanimoto_smiles(self.smiles, self.smiles_dict),
+            self.tanimoto_dict,
+        )
+
+
+class FingerPrinterTestCaseCompound1ECFP4(TestCase):
+    def setUp(self):
+        self.fingerprinter = FingerPrinter("ECFP4")
+        self.smiles = "CC(C)C(=O)c1cc(C(=O)c2ccc(Oc3ccccc3)cc2)c(O)c(O)c1O"
+        self.smiles_dict = {1: "CC(C)C(=O)c1cc(C(=O)c2ccc(Oc3ccccc3)cc2)c(O)" "c(O)c1O"}
+        self.tanimoto_dict = {1: 1.0}
+
+    def test_tanimoto_smiles(self):
+        self.assertEqual(
+            self.fingerprinter.tanimoto_smiles(self.smiles, self.smiles_dict),
+            self.tanimoto_dict,
+        )
+
+
+class ConvertSMILESToSDFTestCase(TestCase):
+    """
+    Test converting a smiles to SDF using openbabel
+    """
+
+    def setUp(self):
+        self.smiles = "C"
+        # the MOL version is also a valid regexp to validate arbitrary name in
+        # the openbabel-generated version
+        self.sdf = (
+            "1\n"
+            " OpenBabel[0-9]{11}D\n"
+            "\n"
+            "  1  0  0  0  0  0  0  0  0  0999 V2000\n"
+            "    0.0000    0.0000    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0\n"
+            "M  END\n"
+            "\$\$\$\$\n"
+        )
+
+    def test_valid(self):
+        result = smi2sdf({1: self.smiles})
+        self.assertTrue(re.compile(self.sdf).search(result))