diff --git a/aidge_core/unit_tests/test_tensor.py b/aidge_core/unit_tests/test_tensor.py
index a214a0e354c64b515d0a7ac24d81c85e116938ca..d479c98b20534daa804f6019b63d528883c2b568 100644
--- a/aidge_core/unit_tests/test_tensor.py
+++ b/aidge_core/unit_tests/test_tensor.py
@@ -10,16 +10,16 @@ SPDX-License-Identifier: EPL-2.0
 
 import unittest
 import aidge_core
-
 from functools import reduce
+
 import numpy as np
 
+
 class test_tensor(unittest.TestCase):
-    """
+    """Test tensor binding
     """
     def setUp(self):
         pass
-
     def tearDown(self):
         pass
 
@@ -35,10 +35,60 @@ class test_tensor(unittest.TestCase):
             idx = t.get_idx(coord)
             self.assertEqual(idx, i)
 
-if __name__ == '__main__':
-    unittest.main()
+    def test_getavailable_backends(self):
+        self.assertTrue("cpu" in aidge_core.Tensor.get_available_backends())
+
+    def test_numpy_int_to_tensor(self):
+        np_array = np.arange(9).reshape(1,1,3,3).astype(np.int32)
+        # Numpy -> Tensor
+        t = aidge_core.Tensor(np_array)
+        self.assertEqual(t.dtype(), aidge_core.DataType.Int32)
+        for i_t, i_n in zip(t, np_array.flatten()):
+            self.assertTrue(i_t == i_n)
+        for i,j in zip(t.dims(), np_array.shape):
+            self.assertEqual(i,j)
+    def test_tensor_int_to_numpy(self):
+        np_array = np.arange(9).reshape(1,1,3,3)
+        # Numpy -> Tensor
+        t = aidge_core.Tensor(np_array)
+        # Tensor -> Numpy
+        nnarray = np.array(t)
+        for i_nn, i_n in zip(nnarray.flatten(), np_array.flatten()):
+            self.assertTrue(i_nn == i_n)
+        for i,j in zip(t.dims(), nnarray.shape):
+            self.assertEqual(i,j)
 
+    def test_numpy_int64_to_tensor(self):
+        np_array = np.arange(9).reshape(1,1,3,3).astype(np.int64)
+        # Numpy -> Tensor
+        t = aidge_core.Tensor(np_array)
+        self.assertEqual(t.dtype(), aidge_core.DataType.Int64)
+        for i_t, i_n in zip(t, np_array.flatten()):
+            self.assertTrue(i_t == i_n)
+        for i,j in zip(t.dims(), np_array.shape):
+            self.assertEqual(i,j)
 
+    def test_numpy_float_to_tensor(self):
+        t = aidge_core.Tensor()
+        np_array = np.random.rand(1, 1, 3, 3).astype(np.float32)
+        # Numpy -> Tensor
+        t = aidge_core.Tensor(np_array)
+        self.assertEqual(t.dtype(), aidge_core.DataType.Float32)
+        for i_t, i_n in zip(t, np_array.flatten()):
+            self.assertTrue(i_t == i_n) # TODO : May need to change this to a difference
+        for i,j in zip(t.dims(), np_array.shape):
+            self.assertEqual(i,j)
 
+    def test_get_set(self):
+        dims = [2,2,2]
 
+        np_array = np.arange(8).reshape(dims).astype(np.int32)
+        # Numpy -> Tensor
+        t = aidge_core.Tensor(np_array)
+        for i in range(8):
+            self.assertEqual(t[i], i)
+            t[i] = 5
+            self.assertEqual(t[i], 5)
 
+if __name__ == '__main__':
+    unittest.main()
diff --git a/unit_tests/data/Test_TensorImpl.cpp b/unit_tests/data/Test_TensorImpl.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..cfcfb45e3735538c1650cfd990ea85e2333916ad
--- /dev/null
+++ b/unit_tests/data/Test_TensorImpl.cpp
@@ -0,0 +1,100 @@
+/********************************************************************************
+ * Copyright (c) 2023 CEA-List
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ ********************************************************************************/
+
+#include <array>
+
+#include <catch2/catch_test_macros.hpp>
+
+#include "aidge/data/Tensor.hpp"
+#include "aidge/utils/TensorUtils.hpp"
+#include "aidge/backend/cpu/data/TensorImpl.hpp"
+
+using namespace Aidge;
+
+TEST_CASE("Tensor creation") {
+  SECTION("from const array") {
+    Tensor x = Array3D<int, 2, 2, 2>{{{{1, 2}, {3, 4}}, {{5, 6}, {7, 8}}}};
+
+    Tensor xCopy = Array3D<int, 2, 2, 2>{{{{1, 2}, {3, 4}}, {{5, 6}, {7, 8}}}};
+
+    Tensor xFloat =
+        Array3D<float, 2, 2, 2>{{{{1., 2.}, {3., 4.}}, {{5., 6.}, {7., 8.}}}};
+
+    SECTION("Tensor features") {
+      REQUIRE(x.nbDims() == 3);
+      REQUIRE(x.dims()[0] == 2);
+      REQUIRE(x.dims()[1] == 2);
+      REQUIRE(x.dims()[2] == 2);
+      REQUIRE(x.size() == 8);
+    }
+
+    SECTION("Access to array") {
+      REQUIRE(static_cast<int *>(x.getImpl()->rawPtr())[0] == 1);
+      REQUIRE(static_cast<int *>(x.getImpl()->rawPtr())[7] == 8);
+    }
+
+    SECTION("get function") {
+      REQUIRE(x.get<int>({0, 0, 0}) == 1);
+      REQUIRE(x.get<int>({0, 0, 1}) == 2);
+      REQUIRE(x.get<int>({0, 1, 1}) == 4);
+      REQUIRE(x.get<int>({1, 1, 0}) == 7);
+      x.set<int>({1, 1, 1}, 36);
+      REQUIRE(x.get<int>({1, 1, 1}) == 36);
+    }
+
+    SECTION("Pretty printing for debug") { REQUIRE_NOTHROW(x.print()); }
+
+    SECTION("Tensor (in)equality") {
+      REQUIRE(x == xCopy);
+      REQUIRE_FALSE(x == xFloat);
+    }
+  }
+}
+
+TEST_CASE("Tensor methods") {
+  Tensor x = Array3D<int, 2, 2, 2>{{
+    {{1, 2},
+     {3, 4}},
+    {{5, 6},
+     {7, 8}}
+  }};
+
+  Tensor xCopy = Array3D<int, 2, 2, 2>{{{{1, 2}, {3, 4}}, {{5, 6}, {7, 8}}}};
+
+  Tensor xFloat =
+      Array3D<float, 2, 2, 2>{{{{1., 2.}, {3., 4.}}, {{5., 6.}, {7., 8.}}}};
+
+  SECTION("Tensor sharing") {
+    Tensor xCopyCtor(x);
+    REQUIRE(xCopyCtor.getImpl() == x.getImpl());
+
+    Tensor xEqOp = x;
+    REQUIRE(xEqOp.getImpl() == x.getImpl());
+
+    Tensor xCloned = x.clone();
+    REQUIRE(xCloned.getImpl() != x.getImpl());
+    REQUIRE(xCloned == x);
+  }
+
+  SECTION("Tensor extract") {
+    Tensor y = x.extract({0, 1});
+    REQUIRE(y.getImpl() == x.getImpl());
+    REQUIRE(approxEq<int>(y, Array1D<int, 2>{{3, 4}}));
+    REQUIRE(y.isContiguous());
+    
+    Tensor y2 = x.extract({0, 1, 1}, {2, 1, 1});
+    REQUIRE(y2.getImpl() == x.getImpl());
+    REQUIRE(!y2.isContiguous());
+    Tensor y3 = y2.clone();
+    REQUIRE(y3.isContiguous());
+    REQUIRE(approxEq<int>(y3, Array3D<int, 2, 1, 1>{{{{4}}, {{8}}}}));
+  }
+}