diff --git a/src/test/java/fr/univlille/sae/classification/knn/MethodKNNTest.java b/src/test/java/fr/univlille/sae/classification/knn/MethodKNNTest.java
index 946657490b368fe5667ceed11896e57a1f7bee91..cbeac973d125e7fde17fe27e2ff564ab5892e911 100644
--- a/src/test/java/fr/univlille/sae/classification/knn/MethodKNNTest.java
+++ b/src/test/java/fr/univlille/sae/classification/knn/MethodKNNTest.java
@@ -1,5 +1,6 @@
 package fr.univlille.sae.classification.knn;
 
+import com.opencsv.exceptions.CsvRequiredFieldEmptyException;
 import fr.univlille.sae.classification.knn.distance.DistanceEuclidienne;
 import fr.univlille.sae.classification.knn.distance.DistanceEuclidienneNormalisee;
 import fr.univlille.sae.classification.model.ClassificationModel;
@@ -41,7 +42,7 @@ public class MethodKNNTest {
 
 
     @Test
-    public void testKVoisins_distance_euclidienne() throws IOException {
+    public void testKVoisins_distance_euclidienne() throws IOException, CsvRequiredFieldEmptyException {
 
         model.loadData(csvTemp);
         List<LoadableData> datas = model.getDatas();
@@ -59,7 +60,7 @@ public class MethodKNNTest {
 
 
     @Test
-    public void testKVoisins_distance_euclidienne_normalise() throws IOException {
+    public void testKVoisins_distance_euclidienne_normalise() throws IOException, CsvRequiredFieldEmptyException {
 
         model.loadData(csvTemp);
         List<LoadableData> datas = model.getDatas();
diff --git a/src/test/java/fr/univlille/sae/classification/knn/distance/DistanceEuclidienneNormaliseeTest.java b/src/test/java/fr/univlille/sae/classification/knn/distance/DistanceEuclidienneNormaliseeTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..e41a60c6e2ebc245ff323ad698d4e68ae72bfad8
--- /dev/null
+++ b/src/test/java/fr/univlille/sae/classification/knn/distance/DistanceEuclidienneNormaliseeTest.java
@@ -0,0 +1,379 @@
+package fr.univlille.sae.classification.knn.distance;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import fr.univlille.sae.classification.knn.MethodKNN;
+import javafx.scene.paint.Color;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import fr.univlille.sae.classification.model.LoadableData;
+
+import java.util.Map;
+
+public class DistanceEuclidienneNormaliseeTest {
+
+    @BeforeAll
+    public static void setupMethodKNN() {
+        MethodKNN.minData = new double[]{0.0, 2.0, 4.0};
+        MethodKNN.amplitude = new double[]{10.0, 3.0, 2.0}; // Assurez-vous que toutes les amplitudes sont non nulles
+    }
+
+    @Test
+    public void testDistanceMatchingAttributes() {
+        LoadableData data1 = new LoadableData() {
+            @Override
+            public String getClassification() {
+                return "";
+            }
+
+            @Override
+            public void setClassificationType(int classificationType) throws IllegalArgumentException, IllegalAccessException {
+
+            }
+
+            @Override
+            public Map<String, Object> getClassifiedAttributes() {
+                return Map.of();
+            }
+
+            @Override
+            public int getClassificationType() {
+                return 0;
+            }
+
+            @Override
+            public void setClassification(String classification) {
+
+            }
+
+            @Override
+            public Map<String, Object> getAttributesNames() {
+                return null;
+            }
+
+            @Override
+            public double[] getAttributes() {
+                return new double[]{2.0, 3.0, 6.0};
+            }
+
+            @Override
+            public String[] getStringAttributes() {
+                return new String[]{"A", "B"};
+            }
+        };
+
+        LoadableData data2 = new LoadableData() {
+            @Override
+            public String getClassification() {
+                return "";
+            }
+
+            @Override
+            public void setClassificationType(int classificationType) throws IllegalArgumentException, IllegalAccessException {
+
+            }
+
+            @Override
+            public Map<String, Object> getClassifiedAttributes() {
+                return Map.of();
+            }
+
+            @Override
+            public int getClassificationType() {
+                return 0;
+            }
+
+            @Override
+            public void setClassification(String classification) {
+
+            }
+
+            @Override
+            public Map<String, Object> getAttributesNames() {
+                return null;
+            }
+            @Override
+            public double[] getAttributes() {
+                return new double[]{8.0, 5.0, 8.0};
+            }
+
+            @Override
+            public String[] getStringAttributes() {
+                return new String[]{"A", "B"};
+            }
+        };
+
+        DistanceEuclidienneNormalisee distance = new DistanceEuclidienneNormalisee();
+        double result = distance.distance(data1, data2);
+        assertEquals(1.3432961119739923, result, 0.0001);
+    }
+
+    @Test
+    public void testDistanceDifferentStringAttributes() {
+        LoadableData data1 = new LoadableData() {
+            @Override
+            public String getClassification() {
+                return "";
+            }
+
+            @Override
+            public void setClassificationType(int classificationType) throws IllegalArgumentException, IllegalAccessException {
+
+            }
+
+            @Override
+            public Map<String, Object> getClassifiedAttributes() {
+                return Map.of();
+            }
+
+            @Override
+            public int getClassificationType() {
+                return 0;
+            }
+
+            @Override
+            public void setClassification(String classification) {
+
+            }
+
+            @Override
+            public Map<String, Object> getAttributesNames() {
+                return null;
+            }
+
+            @Override
+            public double[] getAttributes() {
+                return new double[]{2.0, 3.0, 6.0};
+            }
+
+            @Override
+            public String[] getStringAttributes() {
+                return new String[]{"A", "B"};
+            }
+        };
+
+        LoadableData data2 = new LoadableData() {
+            @Override
+            public String getClassification() {
+                return "";
+            }
+
+            @Override
+            public void setClassificationType(int classificationType) throws IllegalArgumentException, IllegalAccessException {
+
+            }
+
+            @Override
+            public Map<String, Object> getClassifiedAttributes() {
+                return Map.of();
+            }
+
+            @Override
+            public int getClassificationType() {
+                return 0;
+            }
+
+            @Override
+            public void setClassification(String classification) {
+
+            }
+
+            @Override
+            public Map<String, Object> getAttributesNames() {
+                return null;
+            }
+
+            @Override
+            public double[] getAttributes() {
+                return new double[]{8.0, 5.0, 8.0};
+            }
+
+            @Override
+            public String[] getStringAttributes() {
+                return new String[]{"A", "C"};
+            }
+        };
+
+        DistanceEuclidienneNormalisee distance = new DistanceEuclidienneNormalisee();
+        double result = distance.distance(data1, data2);
+        assertEquals(1.674647558277396, result, 0.0001);
+    }
+
+    @Test
+    public void testDistanceDifferentAttributeLengths() {
+        LoadableData data1 = new LoadableData() {
+            @Override
+            public String getClassification() {
+                return "";
+            }
+
+            @Override
+            public void setClassificationType(int classificationType) throws IllegalArgumentException, IllegalAccessException {
+
+            }
+
+            @Override
+            public Map<String, Object> getClassifiedAttributes() {
+                return Map.of();
+            }
+
+            @Override
+            public int getClassificationType() {
+                return 0;
+            }
+
+            @Override
+            public void setClassification(String classification) {
+
+            }
+
+            @Override
+            public Map<String, Object> getAttributesNames() {
+                return null;
+            }
+            @Override
+            public double[] getAttributes() {
+                return new double[]{2.0, 3.0};
+            }
+
+            @Override
+            public String[] getStringAttributes() {
+                return new String[]{"A"};
+            }
+        };
+
+        LoadableData data2 = new LoadableData() {
+            @Override
+            public String getClassification() {
+                return "";
+            }
+
+            @Override
+            public void setClassificationType(int classificationType) throws IllegalArgumentException, IllegalAccessException {
+
+            }
+
+            @Override
+            public Map<String, Object> getClassifiedAttributes() {
+                return Map.of();
+            }
+
+            @Override
+            public int getClassificationType() {
+                return 0;
+            }
+
+            @Override
+            public void setClassification(String classification) {
+
+            }
+
+            @Override
+            public Map<String, Object> getAttributesNames() {
+                return null;
+            }
+            @Override
+            public double[] getAttributes() {
+                return new double[]{8.0, 5.0, 8.0};
+            }
+
+            @Override
+            public String[] getStringAttributes() {
+                return new String[]{"A"};
+            }
+        };
+
+        DistanceEuclidienneNormalisee distance = new DistanceEuclidienneNormalisee();
+        assertThrows(IllegalArgumentException.class, () -> distance.distance(data1, data2));
+    }
+
+    @Test
+    public void testDistanceDifferentStringAttributeLengths() {
+        LoadableData data1 = new LoadableData() {
+            @Override
+            public String getClassification() {
+                return "";
+            }
+
+            @Override
+            public void setClassificationType(int classificationType) throws IllegalArgumentException, IllegalAccessException {
+
+            }
+
+            @Override
+            public Map<String, Object> getClassifiedAttributes() {
+                return Map.of();
+            }
+
+            @Override
+            public int getClassificationType() {
+                return 0;
+            }
+
+            @Override
+            public void setClassification(String classification) {
+
+            }
+
+            @Override
+            public Map<String, Object> getAttributesNames() {
+                return null;
+            }
+            @Override
+            public double[] getAttributes() {
+                return new double[]{2.0, 3.0, 6.0};
+            }
+
+            @Override
+            public String[] getStringAttributes() {
+                return new String[]{"A"};
+            }
+        };
+
+        LoadableData data2 = new LoadableData() {
+            @Override
+            public String getClassification() {
+                return "";
+            }
+
+            @Override
+            public void setClassificationType(int classificationType) throws IllegalArgumentException, IllegalAccessException {
+
+            }
+
+            @Override
+            public Map<String, Object> getClassifiedAttributes() {
+                return Map.of();
+            }
+
+            @Override
+            public int getClassificationType() {
+                return 0;
+            }
+
+            @Override
+            public void setClassification(String classification) {
+
+            }
+
+            @Override
+            public Map<String, Object> getAttributesNames() {
+                return null;
+            }
+
+            @Override
+            public double[] getAttributes() {
+                return new double[]{8.0, 5.0, 8.0};
+            }
+
+            @Override
+            public String[] getStringAttributes() {
+                return new String[]{"A", "B"};
+            }
+        };
+
+        DistanceEuclidienneNormalisee distance = new DistanceEuclidienneNormalisee();
+        assertThrows(IllegalArgumentException.class, () -> distance.distance(data1, data2));
+    }
+}
+
diff --git a/src/test/java/fr/univlille/sae/classification/knn/distance/DistanceEuclidienneTest.java b/src/test/java/fr/univlille/sae/classification/knn/distance/DistanceEuclidienneTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..1ce0de7579cdce86906947b55ce82832b0a2cae1
--- /dev/null
+++ b/src/test/java/fr/univlille/sae/classification/knn/distance/DistanceEuclidienneTest.java
@@ -0,0 +1,376 @@
+package fr.univlille.sae.classification.knn.distance;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import javafx.scene.paint.Color;
+import org.junit.jupiter.api.Test;
+import fr.univlille.sae.classification.model.LoadableData;
+
+import java.util.Map;
+
+public class DistanceEuclidienneTest {
+
+    @Test
+    public void testDistanceMatchingAttributes() {
+        LoadableData data1 = new LoadableData() {
+            @Override
+            public String getClassification() {
+                return "";
+            }
+
+            @Override
+            public void setClassificationType(int classificationType) throws IllegalArgumentException, IllegalAccessException {
+
+            }
+
+            @Override
+            public Map<String, Object> getClassifiedAttributes() {
+                return Map.of();
+            }
+
+            @Override
+            public int getClassificationType() {
+                return 0;
+            }
+
+            @Override
+            public void setClassification(String classification) {
+
+            }
+
+            @Override
+            public Map<String, Object> getAttributesNames() {
+                return null;
+            }
+            @Override
+            public double[] getAttributes() {
+                return new double[]{1.0, 2.0, 3.0};
+            }
+
+            @Override
+            public String[] getStringAttributes() {
+                return new String[]{"A", "B"};
+            }
+        };
+
+        LoadableData data2 = new LoadableData() {
+            @Override
+            public String getClassification() {
+                return "";
+            }
+
+            @Override
+            public void setClassificationType(int classificationType) throws IllegalArgumentException, IllegalAccessException {
+
+            }
+
+            @Override
+            public Map<String, Object> getClassifiedAttributes() {
+                return Map.of();
+            }
+
+            @Override
+            public int getClassificationType() {
+                return 0;
+            }
+
+            @Override
+            public void setClassification(String classification) {
+
+            }
+
+            @Override
+            public Map<String, Object> getAttributesNames() {
+                return null;
+            }
+
+            @Override
+            public double[] getAttributes() {
+                return new double[]{4.0, 6.0, 3.0};
+            }
+
+            @Override
+            public String[] getStringAttributes() {
+                return new String[]{"A", "B"};
+            }
+        };
+
+        DistanceEuclidienne distance = new DistanceEuclidienne();
+        double result = distance.distance(data1, data2);
+
+        assertEquals(5.0, result, 0.0001); // Distance euclidienne entre les deux points
+    }
+
+    @Test
+    public void testDistanceDifferentStringAttributes() {
+        LoadableData data1 = new LoadableData() {
+            @Override
+            public String getClassification() {
+                return "";
+            }
+
+            @Override
+            public void setClassificationType(int classificationType) throws IllegalArgumentException, IllegalAccessException {
+
+            }
+
+            @Override
+            public Map<String, Object> getClassifiedAttributes() {
+                return Map.of();
+            }
+
+            @Override
+            public int getClassificationType() {
+                return 0;
+            }
+
+            @Override
+            public void setClassification(String classification) {
+
+            }
+
+            @Override
+            public Map<String, Object> getAttributesNames() {
+                return null;
+            }
+            @Override
+            public double[] getAttributes() {
+                return new double[]{1.0, 2.0, 3.0};
+            }
+
+            @Override
+            public String[] getStringAttributes() {
+                return new String[]{"A", "B"};
+            }
+        };
+
+        LoadableData data2 = new LoadableData() {
+            @Override
+            public String getClassification() {
+                return "";
+            }
+
+            @Override
+            public void setClassificationType(int classificationType) throws IllegalArgumentException, IllegalAccessException {
+
+            }
+
+            @Override
+            public Map<String, Object> getClassifiedAttributes() {
+                return Map.of();
+            }
+
+            @Override
+            public int getClassificationType() {
+                return 0;
+            }
+
+            @Override
+            public void setClassification(String classification) {
+            }
+            @Override
+            public Map<String, Object> getAttributesNames() {
+                return null;
+            }
+            @Override
+            public double[] getAttributes() {
+                return new double[]{1.0, 2.0, 3.0};
+            }
+
+            @Override
+            public String[] getStringAttributes() {
+                return new String[]{"A", "C"};
+            }
+        };
+
+        DistanceEuclidienne distance = new DistanceEuclidienne();
+        double result = distance.distance(data1, data2);
+
+        assertEquals(1.0, result, 0.0001); // Une différence dans les attributs string
+    }
+
+    @Test
+    public void testDistanceDifferentAttributeLengths() {
+        LoadableData data1 = new LoadableData() {
+            @Override
+            public String getClassification() {
+                return "";
+            }
+
+            @Override
+            public void setClassificationType(int classificationType) throws IllegalArgumentException, IllegalAccessException {
+
+            }
+
+            @Override
+            public Map<String, Object> getClassifiedAttributes() {
+                return Map.of();
+            }
+
+            @Override
+            public int getClassificationType() {
+                return 0;
+            }
+
+            @Override
+            public void setClassification(String classification) {
+
+            }
+
+            @Override
+            public Map<String, Object> getAttributesNames() {
+                return null;
+            }
+            @Override
+            public double[] getAttributes() {
+                return new double[]{1.0, 2.0};
+            }
+
+            @Override
+            public String[] getStringAttributes() {
+                return new String[]{"A"};
+            }
+        };
+
+        LoadableData data2 = new LoadableData() {
+            @Override
+            public String getClassification() {
+                return "";
+            }
+
+            @Override
+            public void setClassificationType(int classificationType) throws IllegalArgumentException, IllegalAccessException {
+
+            }
+
+            @Override
+            public Map<String, Object> getClassifiedAttributes() {
+                return Map.of();
+            }
+
+            @Override
+            public int getClassificationType() {
+                return 0;
+            }
+
+            @Override
+            public void setClassification(String classification) {
+
+            }
+
+            @Override
+            public Map<String, Object> getAttributesNames() {
+                return null;
+            }
+
+            @Override
+            public double[] getAttributes() {
+                return new double[]{1.0, 2.0, 3.0};
+            }
+
+            @Override
+            public String[] getStringAttributes() {
+                return new String[]{"A"};
+            }
+        };
+
+        DistanceEuclidienne distance = new DistanceEuclidienne();
+
+        assertThrows(IllegalArgumentException.class, () -> {
+            distance.distance(data1, data2);
+        });
+    }
+
+    @Test
+    public void testDistanceDifferentStringAttributeLengths() {
+        LoadableData data1 = new LoadableData() {
+            @Override
+            public String getClassification() {
+                return "";
+            }
+
+            @Override
+            public void setClassificationType(int classificationType) throws IllegalArgumentException, IllegalAccessException {
+
+            }
+
+            @Override
+            public Map<String, Object> getClassifiedAttributes() {
+                return Map.of();
+            }
+
+            @Override
+            public int getClassificationType() {
+                return 0;
+            }
+
+            @Override
+            public void setClassification(String classification) {
+
+            }
+
+            @Override
+            public Map<String, Object> getAttributesNames() {
+                return null;
+            }
+
+            @Override
+            public double[] getAttributes() {
+                return new double[]{1.0, 2.0, 3.0};
+            }
+
+            @Override
+            public String[] getStringAttributes() {
+                return new String[]{"A"};
+            }
+        };
+
+        LoadableData data2 = new LoadableData() {
+            @Override
+            public String getClassification() {
+                return "";
+            }
+
+            @Override
+            public void setClassificationType(int classificationType) throws IllegalArgumentException, IllegalAccessException {
+
+            }
+
+            @Override
+            public Map<String, Object> getClassifiedAttributes() {
+                return Map.of();
+            }
+
+            @Override
+            public int getClassificationType() {
+                return 0;
+            }
+
+            @Override
+            public void setClassification(String classification) {
+
+            }
+
+            @Override
+            public Map<String, Object> getAttributesNames() {
+                return null;
+            }
+
+            @Override
+            public double[] getAttributes() {
+                return new double[]{1.0, 2.0, 3.0};
+            }
+
+            @Override
+            public String[] getStringAttributes() {
+                return new String[]{"A", "B"};
+            }
+        };
+
+        DistanceEuclidienne distance = new DistanceEuclidienne();
+
+        assertThrows(IllegalArgumentException.class, () -> {
+            distance.distance(data1, data2);
+        });
+    }
+}
diff --git a/src/test/java/fr/univlille/sae/classification/knn/distance/DistanceManhattanNormaliseeTest.java b/src/test/java/fr/univlille/sae/classification/knn/distance/DistanceManhattanNormaliseeTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..7db233c6970eb3b1ff2da7b892605ed90dfce7b7
--- /dev/null
+++ b/src/test/java/fr/univlille/sae/classification/knn/distance/DistanceManhattanNormaliseeTest.java
@@ -0,0 +1,384 @@
+package fr.univlille.sae.classification.knn.distance;
+
+import fr.univlille.sae.classification.model.LoadableData;
+import fr.univlille.sae.classification.knn.MethodKNN;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.util.Map;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class DistanceManhattanNormaliseeTest {
+
+    private DistanceManhattanNormalisee distanceManhattanNormalisee;
+
+    @BeforeEach
+    void setUp() {
+        distanceManhattanNormalisee = new DistanceManhattanNormalisee();
+
+        // Configurer les valeurs statiques pour la normalisation
+        MethodKNN.minData = new double[]{1.0, 2.0, 0.5};
+        MethodKNN.amplitude = new double[]{4.0, 3.0, 2.5};
+    }
+
+    @Test
+    void testDistance_Calculation() {
+        LoadableData l1 = new LoadableData() {
+            @Override
+            public double[] getAttributes() {
+                return new double[]{2.0, 5.0, 1.0};
+            }
+
+            @Override
+            public String getClassification() {
+                return "Class1";
+            }
+
+            @Override
+            public void setClassificationType(int classificationType) throws IllegalArgumentException, IllegalAccessException {
+
+            }
+
+            @Override
+            public Map<String, Object> getClassifiedAttributes() {
+                return Map.of();
+            }
+
+            @Override
+            public int getClassificationType() {
+                return 0;
+            }
+
+            @Override
+            public void setClassification(String classification) {
+            }
+
+            @Override
+            public Map<String, Object> getAttributesNames() {
+                return null;
+            }
+
+            @Override
+            public String[] getStringAttributes() {
+                return new String[0];
+            }
+        };
+
+        LoadableData l2 = new LoadableData() {
+            @Override
+            public double[] getAttributes() {
+                return new double[]{4.0, 4.0, 2.0};
+            }
+
+            @Override
+            public String getClassification() {
+                return "Class2";
+            }
+
+            @Override
+            public void setClassificationType(int classificationType) throws IllegalArgumentException, IllegalAccessException {
+
+            }
+
+            @Override
+            public Map<String, Object> getClassifiedAttributes() {
+                return Map.of();
+            }
+
+            @Override
+            public int getClassificationType() {
+                return 0;
+            }
+
+            @Override
+            public void setClassification(String classification) {
+            }
+
+            @Override
+            public Map<String, Object> getAttributesNames() {
+                return null;
+            }
+
+            @Override
+            public String[] getStringAttributes() {
+                return new String[0];
+            }
+        };
+
+        double expectedDistance =
+                (Math.abs(2.0 - 4.0) - 1.0) / 4.0 +
+                        (Math.abs(5.0 - 4.0) - 2.0) / 3.0 +
+                        (Math.abs(1.0 - 2.0) - 0.5) / 2.5;
+
+        assertEquals(expectedDistance, distanceManhattanNormalisee.distance(l1, l2), 1e-6);
+    }
+
+    @Test
+    void testDistance_ZeroDistance() {
+        MethodKNN.minData = new double[]{1.0, 1.0, 1.0};
+        LoadableData l1 = new LoadableData() {
+            @Override
+            public double[] getAttributes() {
+                return new double[]{2.0, 2.0, 2.0};
+            }
+
+            @Override
+            public String getClassification() {
+                return "Class1";
+            }
+
+            @Override
+            public void setClassificationType(int classificationType) throws IllegalArgumentException, IllegalAccessException {
+
+            }
+
+            @Override
+            public Map<String, Object> getClassifiedAttributes() {
+                return Map.of();
+            }
+
+            @Override
+            public int getClassificationType() {
+                return 0;
+            }
+
+            @Override
+            public void setClassification(String classification) {
+            }
+
+            @Override
+            public Map<String, Object> getAttributesNames() {
+                return null;
+            }
+
+            @Override
+            public String[] getStringAttributes() {
+                return new String[0];
+            }
+        };
+
+        LoadableData l2 = new LoadableData() {
+            @Override
+            public double[] getAttributes() {
+                return new double[]{1.0, 1.0, 1.0};
+            }
+
+            @Override
+            public String getClassification() {
+                return "Class1";
+            }
+
+            @Override
+            public void setClassificationType(int classificationType) throws IllegalArgumentException, IllegalAccessException {
+
+            }
+
+            @Override
+            public Map<String, Object> getClassifiedAttributes() {
+                return Map.of();
+            }
+
+            @Override
+            public int getClassificationType() {
+                return 0;
+            }
+
+            @Override
+            public void setClassification(String classification) {
+            }
+
+            @Override
+            public Map<String, Object> getAttributesNames() {
+                return null;
+            }
+
+            @Override
+            public String[] getStringAttributes() {
+                return new String[0];
+            }
+        };
+
+        assertEquals(0.0, distanceManhattanNormalisee.distance(l1, l2), 1e-6);
+    }
+
+
+    @Test
+    void testDistance_EmptyAttributes() {
+        LoadableData l1 = new LoadableData() {
+            @Override
+            public double[] getAttributes() {
+                return new double[]{};
+            }
+
+            @Override
+            public String getClassification() {
+                return "Class1";
+            }
+
+            @Override
+            public void setClassificationType(int classificationType) throws IllegalArgumentException, IllegalAccessException {
+
+            }
+
+            @Override
+            public Map<String, Object> getClassifiedAttributes() {
+                return Map.of();
+            }
+
+            @Override
+            public int getClassificationType() {
+                return 0;
+            }
+
+            @Override
+            public void setClassification(String classification) {
+            }
+
+            @Override
+            public Map<String, Object> getAttributesNames() {
+                return null;
+            }
+
+            @Override
+            public String[] getStringAttributes() {
+                return new String[0];
+            }
+        };
+
+        LoadableData l2 = new LoadableData() {
+            @Override
+            public double[] getAttributes() {
+                return new double[]{};
+            }
+
+            @Override
+            public String getClassification() {
+                return "Class2";
+            }
+
+            @Override
+            public void setClassificationType(int classificationType) throws IllegalArgumentException, IllegalAccessException {
+
+            }
+
+            @Override
+            public Map<String, Object> getClassifiedAttributes() {
+                return Map.of();
+            }
+
+            @Override
+            public int getClassificationType() {
+                return 0;
+            }
+
+            @Override
+            public void setClassification(String classification) {
+            }
+
+            @Override
+            public Map<String, Object> getAttributesNames() {
+                return null;
+            }
+
+            @Override
+            public String[] getStringAttributes() {
+                return new String[0];
+            }
+        };
+
+        assertEquals(0.0, distanceManhattanNormalisee.distance(l1, l2), 1e-6);
+    }
+
+    @Test
+    void testDistance_DifferentLengthAttributes() {
+        LoadableData l1 = new LoadableData() {
+            @Override
+            public double[] getAttributes() {
+                return new double[]{2.0, 3.0};
+            }
+
+            @Override
+            public String getClassification() {
+                return "Class1";
+            }
+
+            @Override
+            public void setClassificationType(int classificationType) throws IllegalArgumentException, IllegalAccessException {
+
+            }
+
+            @Override
+            public Map<String, Object> getClassifiedAttributes() {
+                return Map.of();
+            }
+
+            @Override
+            public int getClassificationType() {
+                return 0;
+            }
+
+            @Override
+            public void setClassification(String classification) {
+            }
+
+            @Override
+            public Map<String, Object> getAttributesNames() {
+                return null;
+            }
+
+            @Override
+            public String[] getStringAttributes() {
+                return new String[0];
+            }
+        };
+
+        LoadableData l2 = new LoadableData() {
+            @Override
+            public double[] getAttributes() {
+                return new double[]{2.0};
+            }
+
+            @Override
+            public String getClassification() {
+                return "Class2";
+            }
+
+            @Override
+            public void setClassificationType(int classificationType) throws IllegalArgumentException, IllegalAccessException {
+
+            }
+
+            @Override
+            public Map<String, Object> getClassifiedAttributes() {
+                return Map.of();
+            }
+
+            @Override
+            public int getClassificationType() {
+                return 0;
+            }
+
+            @Override
+            public void setClassification(String classification) {
+            }
+
+            @Override
+            public Map<String, Object> getAttributesNames() {
+                return null;
+            }
+
+            @Override
+            public String[] getStringAttributes() {
+                return new String[0];
+            }
+        };
+
+        Exception exception = assertThrows(
+                ArrayIndexOutOfBoundsException.class,
+                () -> distanceManhattanNormalisee.distance(l1, l2)
+        );
+
+        assertEquals("Index 1 out of bounds for length 1", exception.getMessage());
+    }
+}
diff --git a/src/test/java/fr/univlille/sae/classification/knn/distance/DistanceManhattanTest.java b/src/test/java/fr/univlille/sae/classification/knn/distance/DistanceManhattanTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..3feeeb3a4ff4b12827ca3539cb024a6756b31d63
--- /dev/null
+++ b/src/test/java/fr/univlille/sae/classification/knn/distance/DistanceManhattanTest.java
@@ -0,0 +1,465 @@
+package fr.univlille.sae.classification.knn.distance;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import javafx.scene.paint.Color;
+import org.junit.jupiter.api.Test;
+import fr.univlille.sae.classification.model.LoadableData;
+
+import java.util.Map;
+
+public class DistanceManhattanTest {
+
+    @Test
+    public void testDistanceMatchingAttributes() {
+        LoadableData data1 = new LoadableData() {
+            @Override
+            public String getClassification() {
+                return "";
+            }
+
+            @Override
+            public void setClassificationType(int classificationType) throws IllegalArgumentException, IllegalAccessException {
+
+            }
+
+            @Override
+            public Map<String, Object> getClassifiedAttributes() {
+                return Map.of();
+            }
+
+            @Override
+            public int getClassificationType() {
+                return 0;
+            }
+
+            @Override
+            public void setClassification(String classification) {
+
+            }
+
+            @Override
+            public Map<String, Object> getAttributesNames() {
+                return null;
+            }
+
+            @Override
+            public double[] getAttributes() {
+                return new double[]{2.0, 3.0, 6.0};
+            }
+
+            @Override
+            public String[] getStringAttributes() {
+                return new String[]{"A", "B"};
+            }
+        };
+
+        LoadableData data2 = new LoadableData() {
+            @Override
+            public String getClassification() {
+                return "";
+            }
+
+            @Override
+            public void setClassificationType(int classificationType) throws IllegalArgumentException, IllegalAccessException {
+
+            }
+
+            @Override
+            public Map<String, Object> getClassifiedAttributes() {
+                return Map.of();
+            }
+
+            @Override
+            public int getClassificationType() {
+                return 0;
+            }
+
+            @Override
+            public void setClassification(String classification) {
+
+            }
+
+            @Override
+            public Map<String, Object> getAttributesNames() {
+                return null;
+            }
+
+            @Override
+            public double[] getAttributes() {
+                return new double[]{5.0, 8.0, 3.0};
+            }
+
+            @Override
+            public String[] getStringAttributes() {
+                return new String[]{"A", "B"};
+            }
+        };
+
+        DistanceManhattan distance = new DistanceManhattan();
+        double result = distance.distance(data1, data2);
+        assertEquals(11.0, result, 0.0001);
+    }
+
+    @Test
+    public void testDistanceWithZeros() {
+        LoadableData data1 = new LoadableData() {
+            @Override
+            public String getClassification() {
+                return "";
+            }
+
+            @Override
+            public void setClassificationType(int classificationType) throws IllegalArgumentException, IllegalAccessException {
+
+            }
+
+            @Override
+            public Map<String, Object> getClassifiedAttributes() {
+                return Map.of();
+            }
+
+            @Override
+            public int getClassificationType() {
+                return 0;
+            }
+
+            @Override
+            public void setClassification(String classification) {
+
+            }
+
+            @Override
+            public Map<String, Object> getAttributesNames() {
+                return null;
+            }
+
+            @Override
+            public double[] getAttributes() {
+                return new double[]{0.0, 0.0, 0.0};
+            }
+
+            @Override
+            public String[] getStringAttributes() {
+                return new String[]{"A", "B"};
+            }
+        };
+
+        LoadableData data2 = new LoadableData() {
+            @Override
+            public String getClassification() {
+                return "";
+            }
+
+            @Override
+            public void setClassificationType(int classificationType) throws IllegalArgumentException, IllegalAccessException {
+
+            }
+
+            @Override
+            public Map<String, Object> getClassifiedAttributes() {
+                return Map.of();
+            }
+
+            @Override
+            public int getClassificationType() {
+                return 0;
+            }
+
+            @Override
+            public void setClassification(String classification) {
+
+            }
+
+            @Override
+            public Map<String, Object> getAttributesNames() {
+                return null;
+            }
+
+            @Override
+            public double[] getAttributes() {
+                return new double[]{0.0, 0.0, 0.0};
+            }
+
+            @Override
+            public String[] getStringAttributes() {
+                return new String[]{"A", "B"};
+            }
+        };
+
+        DistanceManhattan distance = new DistanceManhattan();
+        double result = distance.distance(data1, data2);
+        assertEquals(0.0, result, 0.0001);
+    }
+
+    @Test
+    public void testDistanceWithNegativeValues() {
+        LoadableData data1 = new LoadableData() {
+            @Override
+            public String getClassification() {
+                return "";
+            }
+
+            @Override
+            public void setClassificationType(int classificationType) throws IllegalArgumentException, IllegalAccessException {
+
+            }
+
+            @Override
+            public Map<String, Object> getClassifiedAttributes() {
+                return Map.of();
+            }
+
+            @Override
+            public int getClassificationType() {
+                return 0;
+            }
+
+            @Override
+            public void setClassification(String classification) {
+
+            }
+
+            @Override
+            public Map<String, Object> getAttributesNames() {
+                return null;
+            }
+
+            @Override
+            public double[] getAttributes() {
+                return new double[]{-2.0, -3.0, -6.0};
+            }
+
+            @Override
+            public String[] getStringAttributes() {
+                return new String[]{"A", "B"};
+            }
+        };
+
+        LoadableData data2 = new LoadableData() {
+            @Override
+            public String getClassification() {
+                return "";
+            }
+
+            @Override
+            public void setClassificationType(int classificationType) throws IllegalArgumentException, IllegalAccessException {
+
+            }
+
+            @Override
+            public Map<String, Object> getClassifiedAttributes() {
+                return Map.of();
+            }
+
+            @Override
+            public int getClassificationType() {
+                return 0;
+            }
+
+            @Override
+            public void setClassification(String classification) {
+
+            }
+
+            @Override
+            public Map<String, Object> getAttributesNames() {
+                return null;
+            }
+
+            @Override
+            public double[] getAttributes() {
+                return new double[]{2.0, 3.0, 6.0};
+            }
+
+            @Override
+            public String[] getStringAttributes() {
+                return new String[]{"A", "B"};
+            }
+        };
+
+        DistanceManhattan distance = new DistanceManhattan();
+        double result = distance.distance(data1, data2);
+        assertEquals(22.0, result, 0.0001);
+    }
+
+    @Test
+    public void testDistanceWithDifferentAttributeLengths() {
+        LoadableData data1 = new LoadableData() {
+            @Override
+            public String getClassification() {
+                return "";
+            }
+
+            @Override
+            public void setClassificationType(int classificationType) throws IllegalArgumentException, IllegalAccessException {
+
+            }
+
+            @Override
+            public Map<String, Object> getClassifiedAttributes() {
+                return Map.of();
+            }
+
+            @Override
+            public int getClassificationType() {
+                return 0;
+            }
+
+            @Override
+            public void setClassification(String classification) {
+
+            }
+
+            @Override
+            public Map<String, Object> getAttributesNames() {
+                return null;
+            }
+            @Override
+            public double[] getAttributes() {
+                return new double[]{1.0, 2.0};
+            }
+
+            @Override
+            public String[] getStringAttributes() {
+                return new String[]{"A"};
+            }
+        };
+
+        LoadableData data2 = new LoadableData() {
+            @Override
+            public String getClassification() {
+                return "";
+            }
+
+            @Override
+            public void setClassificationType(int classificationType) throws IllegalArgumentException, IllegalAccessException {
+
+            }
+
+            @Override
+            public Map<String, Object> getClassifiedAttributes() {
+                return Map.of();
+            }
+
+            @Override
+            public int getClassificationType() {
+                return 0;
+            }
+
+            @Override
+            public void setClassification(String classification) {
+
+            }
+
+            @Override
+            public Map<String, Object> getAttributesNames() {
+                return null;
+            }
+
+            @Override
+            public double[] getAttributes() {
+                return new double[]{3.0};
+            }
+
+            @Override
+            public String[] getStringAttributes() {
+                return new String[]{"A"};
+            }
+        };
+
+        DistanceManhattan distance = new DistanceManhattan();
+        assertThrows(ArrayIndexOutOfBoundsException.class, () -> distance.distance(data1, data2));
+    }
+
+    @Test
+    public void testDistanceEmptyAttributes() {
+        LoadableData data1 = new LoadableData() {
+            @Override
+            public String getClassification() {
+                return "";
+            }
+
+            @Override
+            public void setClassificationType(int classificationType) throws IllegalArgumentException, IllegalAccessException {
+
+            }
+
+            @Override
+            public Map<String, Object> getClassifiedAttributes() {
+                return Map.of();
+            }
+
+            @Override
+            public int getClassificationType() {
+                return 0;
+            }
+
+            @Override
+            public void setClassification(String classification) {
+
+            }
+
+            @Override
+            public Map<String, Object> getAttributesNames() {
+                return null;
+            }
+
+            @Override
+            public double[] getAttributes() {
+                return new double[]{};
+            }
+
+            @Override
+            public String[] getStringAttributes() {
+                return new String[]{};
+            }
+        };
+
+        LoadableData data2 = new LoadableData() {
+            @Override
+            public String getClassification() {
+                return "";
+            }
+
+            @Override
+            public void setClassificationType(int classificationType) throws IllegalArgumentException, IllegalAccessException {
+
+            }
+
+            @Override
+            public Map<String, Object> getClassifiedAttributes() {
+                return Map.of();
+            }
+
+            @Override
+            public int getClassificationType() {
+                return 0;
+            }
+
+            @Override
+            public void setClassification(String classification) {
+
+            }
+
+            @Override
+            public Map<String, Object> getAttributesNames() {
+                return null;
+            }
+
+            @Override
+            public double[] getAttributes() {
+                return new double[]{};
+            }
+
+            @Override
+            public String[] getStringAttributes() {
+                return new String[]{};
+            }
+        };
+
+        DistanceManhattan distance = new DistanceManhattan();
+        double result = distance.distance(data1, data2);
+        assertEquals(0.0, result, 0.0001);
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/fr/univlille/sae/classification/model/ClassificationModelTest.java b/src/test/java/fr/univlille/sae/classification/model/ClassificationModelTest.java
index d3b5ab5a5667d95348db2a4c152a06126f7e44ca..99c30713f4c2dacfa37dbc74087020cd5aa3eeb7 100644
--- a/src/test/java/fr/univlille/sae/classification/model/ClassificationModelTest.java
+++ b/src/test/java/fr/univlille/sae/classification/model/ClassificationModelTest.java
@@ -1,5 +1,6 @@
 package fr.univlille.sae.classification.model;
 
+import com.opencsv.exceptions.CsvRequiredFieldEmptyException;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
@@ -55,7 +56,7 @@ class ClassificationModelTest {
     }
 
     @Test
-    void testLoadData() throws IOException {
+    void testLoadData() throws IOException, CsvRequiredFieldEmptyException, IllegalAccessException {
 
         model.loadData(csvTemp);
 
@@ -80,7 +81,7 @@ class ClassificationModelTest {
     }
 
     @Test
-    void testClassifierDonnees() {
+    void testClassifierDonnees() throws CsvRequiredFieldEmptyException {
         model.loadData(csvTemp);
 
         model.ajouterDonnee(5.1, 3.5, 1.4, 0.2);
diff --git a/src/test/java/fr/univlille/sae/classification/model/IrisTest.java b/src/test/java/fr/univlille/sae/classification/model/IrisTest.java
index 824be5f4bcf220de6165f03d342622ef2316bb37..2d1e6f290ad7c2aea42a57094a852a0d78f5a8c6 100644
--- a/src/test/java/fr/univlille/sae/classification/model/IrisTest.java
+++ b/src/test/java/fr/univlille/sae/classification/model/IrisTest.java
@@ -32,19 +32,19 @@ class IrisTest {
 
     @Test
     void getDataType() {
-        assertEquals(3.0 , iris.getDataType("sepalWidth"));
-        assertEquals(2.8, iris.getDataType("sepalLength"));
-        assertEquals(4.1, iris.getDataType("petalWidth"));
-        assertEquals(1.9, iris.getDataType("petalLength"));
+        assertEquals(3.0 , iris.getSepalWidth());
+        assertEquals(2.8, iris.getSepalLength());
+        assertEquals(4.1, iris.getPetalWidth());
+        assertEquals(1.9, iris.getPetalLength());
     }
 
-    @Test
-    void getColor() {
-        assertEquals(Color.RED, iris.getClassifications().get(iris.getClassification()));
-    }
+//    @Test
+//    void getColor() throws IllegalAccessException {
+//        assertEquals(Color.RED, iris.getClassifications().get(iris.getClassification()));
+//    }
 
     @Test
     void testToString() {
-        assertEquals("Iris{sepalLength=2.8, sepalWidth=3.0, petalLength=1.9, petalWidth=4.1}", iris.toString());
+        assertEquals("Sepal length: 2.8\nSepal width: 3.0\nPetal length: 1.9\nPetal width: 4.1\nVariety: Setosa", iris.toString());
     }
 }
\ No newline at end of file