diff --git a/src/BPTree.c b/src/BPTree.c
index 9c984e39af841ada2bd3ecb8e8c7677e79c2b6fb..67da7a471c878714cd48757327806bd0db130a1f 100644
--- a/src/BPTree.c
+++ b/src/BPTree.c
@@ -304,7 +304,7 @@ static bool _BPTree_delete(BPTreeNode *root, uint64_t key, BPTreeNode *parent) {
         root->keys->items[index] = find_smallest_key(root->children->items[index + 1]);
     }
 
-    if (parent == NULL && root->keys->size == 0) {
+    if (parent == NULL && !root->is_leaf && root->keys->size == 0) {
         shrink(root);
     }
 
diff --git a/src/Makefile b/src/Makefile
index 5589bd614b3a4f38c7fb4149fde61d4b25d76a43..04628dbb0588d1ca47ee98d85768c998da8490e6 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -22,13 +22,13 @@ $(TARGET): $(OBJECTS)
 
 # TESTS_BEGIN
 
-unity.o: tests/unity.c tests/unity.h
+Unity.o: tests/Unity/unity.c tests/Unity/unity.h
 	$(CC) $(CFLAGS) -c $< -o $@
 
-testtest.o: tests/testtest.c
+BPTreeTests.o: tests/BPTreeTests.c
 	$(CC) $(CFLAGS) -c $< -o $@
 
-make_run_tests: unity.o testtest.o Array.o
+make_run_tests: Unity.o BPTreeTests.o Array.o BPTree.o
 	$(CC) $^ $(CFLAGS) $(LIBS) -o tests_exec
 	./tests_exec || true
 
diff --git a/src/tests/BPTreeTests.c b/src/tests/BPTreeTests.c
new file mode 100644
index 0000000000000000000000000000000000000000..06a1249b06fa437f5d2130a2b83586dd8650e74e
--- /dev/null
+++ b/src/tests/BPTreeTests.c
@@ -0,0 +1,402 @@
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "../Array.h"
+#include "../BPTree.h"
+#include "Unity/unity.h"
+
+#define RANDOM_MIN 0
+#define RANDOM_MAX 1000
+
+BPTreeNode *tree;
+
+void setUp(void) {
+}
+
+void tearDown(void) {
+    if (tree != NULL) {
+        BPTree_destroy(&tree);
+    }
+}
+
+// BEGIN : Compliance with B+ Tree rules
+
+static bool check_if_BPTree_is_compliant_with_the_rules(BPTreeNode *root);
+static bool check_if_the_leaves_are_all_at_the_same_depth(BPTreeNode *root);
+static int compute_first_leaf_depth(BPTreeNode *root);
+static bool _check_if_the_leaves_are_all_at_the_same_depth(BPTreeNode *root, int expected_depth, int depth);
+static bool check_if_all_internal_nodes_have_no_data(BPTreeNode *root);
+static bool check_if_all_leaf_nodes_have_as_much_data_as_keys(BPTreeNode *root);
+static bool check_if_the_keys_are_sorted_in_all_nodes(BPTreeNode *root);
+static bool check_if_the_array_is_sorted(IntegerArray *array);
+static bool check_if_all_nodes_except_the_root_have_not_less_keys_than_the_minimum(BPTreeNode *root, BPTreeNode *parent);
+static bool check_if_all_nodes_have_no_more_keys_than_the_maximum(BPTreeNode *root);
+static bool check_in_all_internal_nodes_there_is_1_child_more_than_the_number_of_keys(BPTreeNode *root);
+static bool check_if_the_keys_are_inserted_in_the_right_place(BPTreeNode *root);
+static bool check_if_the_keys_are_inserted_in_the_right_place_with_range(BPTreeNode *root, uint64_t left, uint64_t right);
+
+static bool check_if_BPTree_is_compliant_with_the_rules(BPTreeNode *root) {
+    bool is_compliant = true;
+    is_compliant &= check_if_the_leaves_are_all_at_the_same_depth(root);
+    is_compliant &= check_if_all_internal_nodes_have_no_data(root);
+    is_compliant &= check_if_all_leaf_nodes_have_as_much_data_as_keys(root);
+    is_compliant &= check_if_the_keys_are_sorted_in_all_nodes(root);
+    is_compliant &= check_if_all_nodes_except_the_root_have_not_less_keys_than_the_minimum(root, NULL);
+    is_compliant &= check_if_all_nodes_have_no_more_keys_than_the_maximum(root);
+    is_compliant &= check_in_all_internal_nodes_there_is_1_child_more_than_the_number_of_keys(root);
+    is_compliant &= check_if_the_keys_are_inserted_in_the_right_place(root);
+    // TODO : check if linked list is ok
+    return is_compliant;
+}
+
+static bool check_if_the_leaves_are_all_at_the_same_depth(BPTreeNode *root) {
+    int expected_depth = compute_first_leaf_depth(root);
+    return _check_if_the_leaves_are_all_at_the_same_depth(root, expected_depth, 0);
+}
+
+static int compute_first_leaf_depth(BPTreeNode *root) {
+    if (root->is_leaf) {
+        return 0;
+    }
+
+    return compute_first_leaf_depth(root->children->items[0]) + 1;
+}
+
+static bool _check_if_the_leaves_are_all_at_the_same_depth(BPTreeNode *root, int expected_depth, int depth) {
+    if (root->is_leaf) {
+        return depth == expected_depth;
+    }
+
+    for (int i = 0; i < root->children->size; i++) {
+        if (!_check_if_the_leaves_are_all_at_the_same_depth(root->children->items[i], expected_depth, depth + 1)) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+static bool check_if_all_internal_nodes_have_no_data(BPTreeNode *root) {
+    if (root->is_leaf) {
+        return true;
+    }
+
+    for (int i = 0; i < root->children->size; i++) {
+        if (!check_if_all_internal_nodes_have_no_data(root->children->items[i])) {
+            return false;
+        }
+    }
+
+    return root->data->size == 0;
+}
+
+static bool check_if_all_leaf_nodes_have_as_much_data_as_keys(BPTreeNode *root) {
+    if (root->is_leaf) {
+        return root->keys->size == root->data->size;
+    }
+
+    for (int i = 0; i < root->children->size; i++) {
+        if (!check_if_all_leaf_nodes_have_as_much_data_as_keys(root->children->items[i])) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+static bool check_if_the_keys_are_sorted_in_all_nodes(BPTreeNode *root) {
+    for (int i = 0; i < root->children->size; i++) {
+        if (!check_if_the_keys_are_sorted_in_all_nodes(root->children->items[i])) {
+            return false;
+        }
+    }
+
+    return check_if_the_array_is_sorted(root->keys);
+}
+
+static bool check_if_the_array_is_sorted(IntegerArray *array) {
+    for (int i = 0; i < array->size - 1; i++) {
+        if (array->items[i] > array->items[i + 1]) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+static bool check_if_all_nodes_except_the_root_have_not_less_keys_than_the_minimum(BPTreeNode *root, BPTreeNode *parent) {
+    for (int i = 0; i < root->children->size; i++) {
+        if (!check_if_all_nodes_except_the_root_have_not_less_keys_than_the_minimum(root->children->items[i], root)) {
+            return false;
+        }
+    }
+
+    if (parent == NULL) {
+        return true;
+    }
+
+    return root->keys->size >= root->order;
+}
+
+static bool check_if_all_nodes_have_no_more_keys_than_the_maximum(BPTreeNode *root) {
+    for (int i = 0; i < root->children->size; i++) {
+        if (!check_if_all_nodes_have_no_more_keys_than_the_maximum(root->children->items[i])) {
+            return false;
+        }
+    }
+
+    return root->keys->size <= 2 * root->order;
+}
+
+static bool check_in_all_internal_nodes_there_is_1_child_more_than_the_number_of_keys(BPTreeNode *root) {
+    if (root->is_leaf) {
+        return true;
+    }
+
+    for (int i = 0; i < root->children->size; i++) {
+        if (!check_in_all_internal_nodes_there_is_1_child_more_than_the_number_of_keys(root->children->items[i])) {
+            return false;
+        }
+    }
+
+    return root->children->size == root->keys->size + 1;
+}
+
+static bool check_if_the_keys_are_inserted_in_the_right_place(BPTreeNode *root) {
+    if (root->is_leaf) {
+        return true;
+    }
+
+    for (int i = 0; i < root->children->size; i++) {
+        if (i == 0) {
+            if (!check_if_the_keys_are_inserted_in_the_right_place_with_range(root->children->items[i], 0, root->keys->items[i])) {
+                return false;
+            }
+        } else if (i == root->children->size - 1) {
+            if (!check_if_the_keys_are_inserted_in_the_right_place_with_range(root->children->items[i], root->keys->items[i - 1], 18446744073709551615LLU)) {
+                return false;
+            }
+        } else {
+            if (!check_if_the_keys_are_inserted_in_the_right_place_with_range(root->children->items[i], root->keys->items[i - 1], root->keys->items[i])) {
+                return false;
+            }
+        }
+    }
+
+    for (int i = 0; i < root->children->size; i++) {
+        if (!check_if_the_keys_are_inserted_in_the_right_place(root->children->items[i])) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+static bool check_if_the_keys_are_inserted_in_the_right_place_with_range(BPTreeNode *root, uint64_t left, uint64_t right) {
+    for (int i = 0; i < root->keys->size; i++) {
+        if (root->keys->items[i] < left || root->keys->items[i] >= right) {
+            return false;
+        }
+    }
+
+    for (int i = 0; i < root->children->size; i++) {
+        if (!check_if_the_keys_are_inserted_in_the_right_place_with_range(root->children->items[i], left, right)) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+// END : BPTree Compliance
+
+/**
+ * @brief Performs a linear search for an item in an array.
+ *
+ * @param array The array in which the search is to be performed.
+ * @param item The item searched for.
+ * @return true The item has been found.
+ * @return false The item was not found.
+ */
+static bool IntegerArray_search(IntegerArray *array, uint64_t item) {
+    for (int i = 0; i < array->size; i++) {
+        if (array->items[i] == item) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+/**
+ * @brief Generates an array of random numbers.
+ *
+ * @param size The number of numbers to generate.
+ * @param random_min The smallest random value.
+ * @param random_max The greatest random value.
+ * @return IntegerArray* The random number array.
+ */
+static IntegerArray *generate_random_numbers_array(int size, int random_min, int random_max) {
+    IntegerArray *array = IntegerArray_init(size);
+
+    for (int i = 0; i < size; i++) {
+        uint64_t number;
+
+        // While the generated random nomber already exists in the array.
+        do {
+            number = random_min + rand() % (random_max - random_min);
+        } while (IntegerArray_search(array, number));
+
+        IntegerArray_append(array, number);
+    }
+
+    return array;
+}
+
+static uint64_t transform_key_to_data(uint64_t key) {
+    return key * 10000;
+}
+
+// BEGIN : Tests
+
+// **** BEGIN : test_BPTree_insert
+
+static void test_BPTree_insert_should_comply_with_BPTree_rules_using_BPTree_of_given_order(BPTreeNode **root, int order) {
+    int size = 1;
+
+    // Test 10 times, variable i being the seed.
+    for (int i = 0; i < 10; i++) {
+        srand(i);
+
+        // Test with seed "i" 8 array size, at each end of loop the size variable is multiplied by 2, the array of random keys
+        // will have the size of 1 then 2, 4, 8, 16, 32, ...
+        for (int j = 0; j < 8; j++) {
+            IntegerArray *keys = generate_random_numbers_array(size, RANDOM_MIN, RANDOM_MAX);
+            *root = BPTree_init(order);
+
+            for (int i = 0; i < keys->size; i++) {
+                BPTree_insert(*root, keys->items[i], transform_key_to_data(keys->items[i]));
+                // After each insertion is verified that the B+ Tree is compliant with the rules.
+                TEST_ASSERT(check_if_BPTree_is_compliant_with_the_rules(*root));
+            }
+
+            IntegerArray_destroy(&keys);
+            BPTree_destroy(root);
+
+            size *= 2;
+        }
+
+        size = 1;
+    }
+}
+
+void test_BPTree_insert_should_comply_with_BPTree_rules_using_BPTree_of_order_1() {
+    test_BPTree_insert_should_comply_with_BPTree_rules_using_BPTree_of_given_order(&tree, 1);
+}
+
+void test_BPTree_insert_should_comply_with_BPTree_rules_using_BPTree_of_order_2() {
+    test_BPTree_insert_should_comply_with_BPTree_rules_using_BPTree_of_given_order(&tree, 2);
+}
+
+void test_BPTree_insert_should_comply_with_BPTree_rules_using_BPTree_of_order_3() {
+    test_BPTree_insert_should_comply_with_BPTree_rules_using_BPTree_of_given_order(&tree, 3);
+}
+
+void test_BPTree_insert_should_comply_with_BPTree_rules_using_BPTree_of_order_4() {
+    test_BPTree_insert_should_comply_with_BPTree_rules_using_BPTree_of_given_order(&tree, 4);
+}
+
+void test_BPTree_insert_should_comply_with_BPTree_rules_using_BPTree_of_order_8() {
+    test_BPTree_insert_should_comply_with_BPTree_rules_using_BPTree_of_given_order(&tree, 8);
+}
+
+void test_BPTree_insert_should_comply_with_BPTree_rules_using_BPTree_of_order_16() {
+    test_BPTree_insert_should_comply_with_BPTree_rules_using_BPTree_of_given_order(&tree, 16);
+}
+
+// **** END : test_BPTree_insert
+
+// **** BEGIN : test_BPTree_delete
+
+void test_BPTree_delete_should_comply_with_BPTree_rules_using_BPTree_of_given_order(BPTreeNode **root, int order) {
+    int size = 1;
+
+    // Test 10 times, variable i being the seed.
+    for (int i = 0; i < 10; i++) {
+        srand(i);
+
+        // Test with seed "i" 8 array size, at each end of loop the size variable is multiplied by 2, the array of random keys
+        // will have the size of 1 then 2, 4, 8, 16, 32, ...
+        for (int j = 0; j < 8; j++) {
+            IntegerArray *keys = generate_random_numbers_array(size, RANDOM_MIN, RANDOM_MAX);
+            *root = BPTree_init(order);
+
+            for (int i = 0; i < keys->size; i++) {
+                BPTree_insert(*root, keys->items[i], transform_key_to_data(keys->items[i]));
+            }
+
+            while (keys->size > 0) {
+                int index = rand() % keys->size;
+                BPTree_delete(*root, keys->items[index]);
+                IntegerArray_delete_at_index(keys, index);
+            }
+
+            IntegerArray_destroy(&keys);
+            BPTree_destroy(&(*root));
+
+            size *= 2;
+        }
+
+        size = 1;
+    }
+}
+
+void test_BPTree_delete_should_comply_with_BPTree_rules_using_BPTree_of_order_1() {
+    test_BPTree_delete_should_comply_with_BPTree_rules_using_BPTree_of_given_order(&tree, 1);
+}
+
+void test_BPTree_delete_should_comply_with_BPTree_rules_using_BPTree_of_order_2() {
+    test_BPTree_delete_should_comply_with_BPTree_rules_using_BPTree_of_given_order(&tree, 2);
+}
+
+void test_BPTree_delete_should_comply_with_BPTree_rules_using_BPTree_of_order_3() {
+    test_BPTree_delete_should_comply_with_BPTree_rules_using_BPTree_of_given_order(&tree, 3);
+}
+
+void test_BPTree_delete_should_comply_with_BPTree_rules_using_BPTree_of_order_4() {
+    test_BPTree_delete_should_comply_with_BPTree_rules_using_BPTree_of_given_order(&tree, 4);
+}
+
+void test_BPTree_delete_should_comply_with_BPTree_rules_using_BPTree_of_order_8() {
+    test_BPTree_delete_should_comply_with_BPTree_rules_using_BPTree_of_given_order(&tree, 8);
+}
+
+void test_BPTree_delete_should_comply_with_BPTree_rules_using_BPTree_of_order_16() {
+    test_BPTree_delete_should_comply_with_BPTree_rules_using_BPTree_of_given_order(&tree, 16);
+}
+
+// **** END : test_BPTree_delete
+
+// END : Tests
+
+int main(void) {
+    UNITY_BEGIN();
+
+    RUN_TEST(test_BPTree_insert_should_comply_with_BPTree_rules_using_BPTree_of_order_1);
+    RUN_TEST(test_BPTree_insert_should_comply_with_BPTree_rules_using_BPTree_of_order_2);
+    RUN_TEST(test_BPTree_insert_should_comply_with_BPTree_rules_using_BPTree_of_order_3);
+    RUN_TEST(test_BPTree_insert_should_comply_with_BPTree_rules_using_BPTree_of_order_4);
+    RUN_TEST(test_BPTree_insert_should_comply_with_BPTree_rules_using_BPTree_of_order_8);
+    RUN_TEST(test_BPTree_insert_should_comply_with_BPTree_rules_using_BPTree_of_order_16);
+
+    RUN_TEST(test_BPTree_delete_should_comply_with_BPTree_rules_using_BPTree_of_order_1);
+    RUN_TEST(test_BPTree_delete_should_comply_with_BPTree_rules_using_BPTree_of_order_2);
+    RUN_TEST(test_BPTree_delete_should_comply_with_BPTree_rules_using_BPTree_of_order_3);
+    RUN_TEST(test_BPTree_delete_should_comply_with_BPTree_rules_using_BPTree_of_order_4);
+    RUN_TEST(test_BPTree_delete_should_comply_with_BPTree_rules_using_BPTree_of_order_8);
+    RUN_TEST(test_BPTree_delete_should_comply_with_BPTree_rules_using_BPTree_of_order_16);
+
+    return UNITY_END();
+}
diff --git a/src/tests/unity.c b/src/tests/Unity/unity.c
similarity index 100%
rename from src/tests/unity.c
rename to src/tests/Unity/unity.c
diff --git a/src/tests/unity.h b/src/tests/Unity/unity.h
similarity index 100%
rename from src/tests/unity.h
rename to src/tests/Unity/unity.h
diff --git a/src/tests/unity_internals.h b/src/tests/Unity/unity_internals.h
similarity index 100%
rename from src/tests/unity_internals.h
rename to src/tests/Unity/unity_internals.h
diff --git a/src/tests/testtest.c b/src/tests/testtest.c
deleted file mode 100644
index db9d3a7a4f4f32c116b9ead2a0ecf483012b8e93..0000000000000000000000000000000000000000
--- a/src/tests/testtest.c
+++ /dev/null
@@ -1,24 +0,0 @@
-#include "../Array.h"
-#include "unity.h"
-
-IntegerArray *array;
-
-void setUp(void) {
-    array = IntegerArray_init(4);
-}
-
-void tearDown(void) {
-    IntegerArray_destroy(&array);
-}
-
-void test_function_should_doAlsoDoBlah(void) {
-    IntegerArray_append(array, 10);
-    TEST_ASSERT_EQUAL_INT(1, array->size);
-    TEST_ASSERT_EQUAL_INT(11, array->items[0]);
-}
-
-int main(void) {
-    UNITY_BEGIN();
-    RUN_TEST(test_function_should_doAlsoDoBlah);
-    return UNITY_END();
-}