diff --git a/raytracing/rays.py b/raytracing/rays.py
index aaf1971..83ffaf1 100644
--- a/raytracing/rays.py
+++ b/raytracing/rays.py
@@ -288,9 +288,9 @@ class RandomRays(Rays):
 
     def __getitem__(self, item):
         if self.rays is None:
-            raise NotImplemented("You cannot access RandomRays")
+            raise NotImplementedError("You cannot access RandomRays")
         elif len(self.rays) < item:
-            raise NotImplemented("You cannot access RandomRays")
+            raise NotImplementedError("You cannot access RandomRays")
         else:
             return self.rays[item]
 
@@ -301,7 +301,7 @@ class RandomRays(Rays):
         return self.randomRay()
 
     def randomRay(self) -> Ray:
-        raise NotImplemented("You must implement randomRay() in your subclass")
+        raise NotImplementedError("You must implement randomRay() in your subclass")
 
 
 class RandomUniformRays(RandomRays):

diff --git a/raytracing/tests/testsComponents.py b/raytracing/tests/testsComponents.py
new file mode 100644
index 0000000..a4aba5b
--- /dev/null
+++ b/raytracing/tests/testsComponents.py
@@ -0,0 +1,60 @@
+import unittest
+import envtest  # modifies path
+from raytracing import *
+
+inf = float("+inf")
+
+
+class Test4fSystem(unittest.TestCase):
+
+    def test4fSystem(self):
+        elements = [Space(10), Lens(10), Space(15), Lens(5), Space(5)]
+        mg = MatrixGroup(elements, label="4f system")
+        system = System4f(10, 5, label="4f system")
+        self.assertEqual(system.A, -0.5)
+        self.assertEqual(system.B, 0)
+        self.assertEqual(system.C, 0)
+        self.assertEqual(system.D, -2)
+        self.assertEqual(system.L, 30)
+        self.assertEqual(mg.backIndex, system.backIndex)
+        self.assertEqual(mg.frontIndex, system.frontIndex)
+        self.assertEqual(mg.backVertex, system.backVertex)
+        self.assertEqual(mg.frontVertex, system.frontVertex)
+        self.assertEqual(mg.label, system.label)
+        self.assertTrue(system.isImaging)
+
+    def test2fSystem(self):
+        elements = [Space(10), Lens(10), Space(10)]
+        mg = MatrixGroup(elements, label="2f system")
+        system = System2f(10, label="2f system")
+        self.assertEqual(system.A, 0)
+        self.assertEqual(system.B, 10)
+        self.assertEqual(system.C, -1 / 10)
+        self.assertEqual(system.D, 0)
+        self.assertEqual(system.L, 20)
+        self.assertEqual(mg.backIndex, system.backIndex)
+        self.assertEqual(mg.frontIndex, system.frontIndex)
+        self.assertEqual(mg.backVertex, system.backVertex)
+        self.assertEqual(mg.frontVertex, system.frontVertex)
+        self.assertEqual(mg.label, system.label)
+        self.assertFalse(system.isImaging)
+
+    def test4fIsTwo2f(self):
+        f1, f2 = 10, 12
+        system4f = System4f(f1=10, f2=12)
+        system2f_1 = System2f(f1)
+        system2f_2 = System2f(f2)
+        composed4fSystem = MatrixGroup(system2f_1.elements + system2f_2.elements)
+        self.assertEqual(composed4fSystem.A, system4f.A)
+        self.assertEqual(composed4fSystem.B, system4f.B)
+        self.assertEqual(composed4fSystem.C, system4f.C)
+        self.assertEqual(composed4fSystem.D, system4f.D)
+        self.assertEqual(composed4fSystem.L, system4f.L)
+        self.assertEqual(composed4fSystem.backIndex, system4f.backIndex)
+        self.assertEqual(composed4fSystem.frontIndex, system4f.frontIndex)
+        self.assertEqual(composed4fSystem.backVertex, system4f.backVertex)
+        self.assertEqual(composed4fSystem.frontVertex, system4f.frontVertex)
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/raytracing/tests/testsRaysSubclasses.py b/raytracing/tests/testsRaysSubclasses.py
new file mode 100644
index 0000000..0b3710d
--- /dev/null
+++ b/raytracing/tests/testsRaysSubclasses.py
@@ -0,0 +1,14 @@
+import unittest
+import envtest  # modifies path
+from raytracing import *
+
+inf = float("+inf")
+
+
+class TestRandomRays(unittest.TestCase):
+
+    def testRandomRay(self):
+        rays = RandomRays()  # We keep default value, we are not intersted in the construction of a specific object
+        with self.assertRaises(NotImplementedError):
+            # This works
+            rays.randomRay()

RandomRays raises a constant, not an exception
In `RandomRays`, some methods have `raise NotImplemented("...")`, but `NotImplemented` is a constant used in some binary methods (see https://docs.python.org/3/library/constants.html). I suspect what we want is `raise NotImplementedError("...")`.
raytracing/tests/testsRaysSubclasses.py::TestRandomRays::testRandomRay
raytracing/tests/testsComponents.py::Test4fSystem::test2fSystem raytracing/tests/testsComponents.py::Test4fSystem::test4fIsTwo2f raytracing/tests/testsComponents.py::Test4fSystem::test4fSystem