From e0537dda8f933e2daac5cd109c8297c090f02c9c Mon Sep 17 00:00:00 2001 From: Sara Date: Mon, 15 Dec 2025 12:42:02 +0100 Subject: [PATCH] comments unit tests --- makefile | 6 ++--- stack.c | 4 +-- test_numbers.c | 33 ++++++++++++----------- test_stack.c | 72 ++++++++++++++++++++++++-------------------------- 4 files changed, 57 insertions(+), 58 deletions(-) diff --git a/makefile b/makefile index d397220..c691dc3 100644 --- a/makefile +++ b/makefile @@ -60,12 +60,12 @@ highscore.o: highscore.c #unitTests: # echo "needs to be implemented" -numbersTests: numbers.o bintree.o test_numbers.c $(unityfolder)/unity.c - $(CC) $(CFLAGS) -I$(unityfolder) -o runNumbersTests test_numbers.c numbers.o bintree.o $(unityfolder)/unity.c - stackTests: stack.o test_stack.c $(unityfolder)/unity.c $(CC) $(CFLAGS) -I$(unityfolder) -o runStackTests test_stack.c stack.o $(unityfolder)/unity.c +numbersTests: numbers.o bintree.o stack.o test_numbers.c $(unityfolder)/unity.c + $(CC) $(CFLAGS) -I$(unityfolder) -o runNumbersTests test_numbers.c numbers.o bintree.o stack.o $(unityfolder)/unity.c + # -------------------------- # Clean # -------------------------- diff --git a/stack.c b/stack.c index efad5fb..dab0eec 100644 --- a/stack.c +++ b/stack.c @@ -19,11 +19,9 @@ StackNode *push(StackNode *stack, void *data) newNode->next = stack; // Der bisherige Stack ist jetzt der Nächste (LIFO) return newNode; // Der neue Knoten ist jetzt die Spitze des Stacks - } -// Deletes the top element of the stack (latest added element) and releases its memory. (Pointer to data has to be -// freed by caller.) +// Deletes the top element of the stack (latest added element) and releases its memory. (Pointer to data has to be freed by caller.) StackNode *pop(StackNode *stack) { // Check, ob der Stack leer ist diff --git a/test_numbers.c b/test_numbers.c index 6d47a3a..fece8db 100644 --- a/test_numbers.c +++ b/test_numbers.c @@ -20,6 +20,8 @@ extern int compareNumbers(const void *arg1, const void *arg2); * @param numbers Das zu prüfende Array. * @param len Die Länge des Arrays. */ + +//Das Array enthält exakt (len-2) Unikate und 1 Duplikat static int validateArrayHasSingleDuplicate(const unsigned int *numbers, unsigned int len) { if (len < 3) return 0; @@ -70,26 +72,26 @@ static int validateArrayHasSingleDuplicate(const unsigned int *numbers, unsigned // TESTFALL GRUPPE 1: createNumbers (KERNFUNKTION) // ========================================================================= -// Prüft die wichtigste Anforderung: Korrekte Allokation, Länge, Duplikat-Struktur und Wertebereich. +// Prüft die wichtigste Anforderung: Zufallsgenerierung, Duplikatprüfung (via BST) und korrekte Array-Struktur void test_createNumbersCoreFunctionality(void) { - const unsigned int len = 10; - unsigned int *numbers = createNumbers(len); + const unsigned int len = 10; // Definiert Array-Größe (10) für den Test + unsigned int *numbers = createNumbers(len); // Ruft createNumbers-Fkt auf - TEST_ASSERT_NOT_NULL(numbers); // Muss Speicher allokieren + TEST_ASSERT_NOT_NULL(numbers); // prüft ob Speicher allokiert worden ist - // 1. Prüfe, ob genau ein Duplikat vorhanden ist (mit Helper-Funktion) + // 1. Prüfe, ob genau ein Duplikat und sonst unikate vorhanden ist (mit Hilffunktion) TEST_ASSERT_TRUE(validateArrayHasSingleDuplicate(numbers, len)); // 2. Prüfe, ob die Duplikat-Findung funktioniert (Test der Integration von getDuplicate) - unsigned int duplicate = getDuplicate(numbers, len); + unsigned int duplicate = getDuplicate(numbers, len); // getDuplicate-Fkt sucht das Duplikat aus dem gerade erzeugtem array mit qsort TEST_ASSERT_TRUE(duplicate != 0); // Muss eine doppelte Zahl finden // 3. Prüfe, ob die Zahlen im erwarteten Bereich [1, 2 * len] liegen - const unsigned int max_val = 2 * len; - for (unsigned int i = 0; i < len; i++) + const unsigned int max_val = 2 * len; //maximale größe der zahlen ist 2*len = hier 20 + for (unsigned int i = 0; i < len; i++) // Geht dasss array (len=10) durch und prüft ob die zahlen zwischen 1 und 20 liegen { - TEST_ASSERT_TRUE(numbers[i] >= 1); + TEST_ASSERT_TRUE(numbers[i] >= 1); // TEST_ASSERT_TRUE(numbers[i] <= max_val); } @@ -105,9 +107,9 @@ void test_createNumbersCoreFunctionality(void) // Prüft die Duplikaterkennung über qsort auf einem unsortierten Array. void test_getDuplicateFindsDuplicatedNumber(void) { - // Testfall: Duplikat in der Mitte eines unsortierten Arrays - unsigned int testArray[] = {10, 5, 20, 30, 5}; - TEST_ASSERT_EQUAL_UINT(5, getDuplicate(testArray, 5)); + + unsigned int testArray[] = {10, 5, 20, 30, 5}; //Definiert ein unsortiertes Array mit dem Duplikat 5 + TEST_ASSERT_EQUAL_UINT(5, getDuplicate(testArray, 5)); //Ruft getDuplicate auf, die intern qsort aufruft; Der Test erwartet die Zahl 5 und vergleicht } @@ -120,14 +122,15 @@ void test_compareNumbersCheckAllCases(void) { unsigned int a = 10, b = 5, c = 10; + //Aufrufen der compareNumbers-fkt // Fall 1: a > b (muss positiv sein) - TEST_ASSERT_TRUE(compareNumbers(&a, &b) > 0); + TEST_ASSERT_TRUE(compareNumbers(&a, &b) > 0); // (10 > 5) -> return 1 > 0 -> positiver Wert -> True // Fall 2: b < a (muss negativ sein) - TEST_ASSERT_TRUE(compareNumbers(&b, &a) < 0); + TEST_ASSERT_TRUE(compareNumbers(&b, &a) < 0); // (5 < 10) -> return -1 < 0 -> negativer Wert -> True // Fall 3: a = c (muss null sein) - TEST_ASSERT_EQUAL_INT(0, compareNumbers(&a, &c)); + TEST_ASSERT_EQUAL_INT(0, compareNumbers(&a, &c)); // (10 = 10) -> return 0 == 0 -> True } diff --git a/test_stack.c b/test_stack.c index b820b44..96fbc15 100644 --- a/test_stack.c +++ b/test_stack.c @@ -42,81 +42,79 @@ static void clearStackWithData(StackNode *stack) // DIE WICHTIGSTEN TESTFÄLLE (REDUZIERT) // ========================================================================= -// Testet Push und Top (LIFO-Prinzip, 1 Element) +// Testet ob das oberste Element (top) korrekt das zuletzt hinzugefügte Element (push) ist void test_pushAndTop(void) { - StackNode *stack = NULL; - int *data = createIntPointer(42); + StackNode *stack = NULL; // Initialisiert den Stack als leeren Pointer. + int *data = createIntPointer(42); // Erzeugt Integer-Wert (42) auf dem Heap // 1. Push - stack = push(stack, data); - TEST_ASSERT_NOT_NULL(stack); + stack = push(stack, data); //Ruft push-Funktion auf; neuer Knoten oben auf den stack + TEST_ASSERT_NOT_NULL(stack); // Prüfung -> Stack-Pointer darf nach dem Pushen nicht NULL sein (siehe unity.h) - // 2. Top (LIFO - Last In) - int *top_data = (int *)top(stack); - TEST_ASSERT_EQUAL_INT(42, *top_data); + // 2. Top + int *top_data = (int *)top(stack); // Ruft top-Funktion auf; Holt void* Pointer von oben und castet ihn zurück zu int* + TEST_ASSERT_EQUAL_INT(42, *top_data);// Prüft, ob der Wert an der Spitze tatsächlich 42 ist - // Aufräumen: Da die Daten hier nur einmalig gepusht wurden, - // können wir den Knoten poppen und die Daten separat freigeben (wie es pop() erfordert). - stack = pop(stack); - free(data); - TEST_ASSERT_NULL(stack); + //clean-up + stack = pop(stack); // pop-Funktion: Entfernt den obersten Knoten und gibt seinen Speicher frei. + free(data); // Gibt den Datenpointer (42) frei + TEST_ASSERT_NULL(stack); // Prüft ob stack jetzt wieder NULL ist } -// Testet die LIFO-Reihenfolge mit mehreren Elementen und die Pop-Funktion. +// Testet die korrekte LIFO-Reihenfolge mit mehreren Elementen und die Pop-Funktion. void test_popMultipleElements(void) { StackNode *stack = NULL; + + // Erzeugt drei separate Integer-Werte (1, 2, 3) auf dem Heap int *data1 = createIntPointer(1); int *data2 = createIntPointer(2); int *data3 = createIntPointer(3); - // Stack: [3 (oben), 2, 1 (unten)] - stack = push(NULL, data1); - stack = push(stack, data2); - stack = push(stack, data3); + // stack befüllen mit push-Funktion + stack = push(NULL, data1); // Stack: [1] (1 ist unten) + stack = push(stack, data2); // Stack: [2, 1] + stack = push(stack, data3); // Stack: [3, 2, 1] (3 ist oben, LIFO). - // 1. Pop: Prüfe 3 - TEST_ASSERT_EQUAL_INT(3, *(int *)top(stack)); - free(data3); - stack = pop(stack); + // 1. Pop: Prüfe ob 3 oben liegt + TEST_ASSERT_EQUAL_INT(3, *(int *)top(stack)); // vergleicht 3 mit top-fkt ausgabe (siehe unity.h) + free(data3); //Gibt den Heap-Speicher frei + stack = pop(stack); //Entfernt den Knoten 3; Stack ist jetzt [2, 1] // 2. Pop: Prüfe 2 - TEST_ASSERT_EQUAL_INT(2, *(int *)top(stack)); + TEST_ASSERT_EQUAL_INT(2, *(int *)top(stack)); //vergleicht 2 mit top-fkt ausgabe (siehe unity.h) free(data2); - stack = pop(stack); + stack = pop(stack); //Entfernt den Knoten 2; Stack ist jetzt [1] // 3. Pop: Prüfe 1 - TEST_ASSERT_EQUAL_INT(1, *(int *)top(stack)); + TEST_ASSERT_EQUAL_INT(1, *(int *)top(stack)); //vergleicht 1 mit top-fkt ausgabe (siehe unity.h) free(data1); - stack = pop(stack); + stack = pop(stack); //Entfernt den Knoten 2; Stack ist jetzt NULL - TEST_ASSERT_NULL(stack); + TEST_ASSERT_NULL(stack); //Prüft ob Stack NULL ist } -// Testet den Grenzfall: Pop auf einem leeren Stack. +// Testet den Grenzfall: Pop auf einem leeren Stack -> soll NULL zurückgeben void test_popOnEmptyStack(void) { - StackNode *stack = NULL; - // Pop sollte NULL zurückgeben, wenn der Stack leer ist. - TEST_ASSERT_NULL(pop(stack)); + StackNode *stack = NULL; //Initialisiert leeren Stack + + TEST_ASSERT_NULL(pop(stack));// Pop sollte NULL zurückgeben, wenn der Stack leer ist } -// Testet die Speicherfreigabe (die wichtigste Anforderung der Aufgabenstellung). +// Testet die Speicherfreigabe void test_clearStackFunctionality(void) { StackNode *stack = NULL; // Allokiere Daten und pushe sie auf den Stack - stack = push(stack, createIntPointer(10)); + stack = push(stack, createIntPointer(10)); //Knoten mit zugehörigem Pointer mit Hilfsfkt stack = push(stack, createIntPointer(20)); stack = push(stack, createIntPointer(30)); - // Die Helferfunktion clearStackWithData ruft free() auf allen Knoten und Daten auf. - // Wir prüfen implizit, ob die clearStack Logik fehlerfrei durchläuft. - clearStackWithData(stack); + clearStackWithData(stack); // gibt iterativ alle Daten und Knoten frei stack = NULL; - // Wenn der Test ohne Speicherzugriffsverletzung durchläuft, war clearStack erfolgreich. }