#include #include #include #include #include "numbers.h" #include "unity.h" // --- UNITY FRAMEWORK NOTWENDIGKEITEN --- // Diese Funktionen MÜSSEN existieren, damit unity.c gelinkt werden kann. void setUp(void) { // Hier könnte Code stehen, der vor jedem Test läuft. // Wir lassen es leer. } void tearDown(void) { // Hier könnte Code stehen, der nach jedem Test aufräumt. // Wir lassen es leer. } // --- HILFSFUNKTIONEN --- // WICHTIG: Diese Funktion muss VOR ihrer Verwendung definiert sein. // Wir nennen sie "compare_helper" und machen sie "static". static int compare_helper(const void *a, const void *b) { unsigned int arg1 = *(const unsigned int*)a; unsigned int arg2 = *(const unsigned int*)b; if (arg1 < arg2) return -1; if (arg1 > arg2) return 1; return 0; } static unsigned int count_occurrences(const unsigned int arr[], unsigned int len, unsigned int value) { unsigned int count = 0; for (unsigned int i = 0; i < len; i++) { if (arr[i] == value) { count++; } } return count; } // Makro für einfache Test-Prüfung #define ASSERT_TRUE(condition, message) \ do { \ if (!(condition)) { \ fprintf(stderr, "FEHLER in %s, Zeile %d: %s\n", __FILE__, __LINE__, message); \ return 0; \ } \ } while (0) // --- TEST FUNKTIONEN --- int test_createNumbers_basic() { // Setzt den Zufallszahlengenerator srand(time(NULL)); unsigned int len = 10; unsigned int *arr = createNumbers(len); ASSERT_TRUE(arr != NULL, "createNumbers sollte bei len=10 nicht NULL zurueckgeben."); // Sortiere eine Kopie unsigned int *temp_copy = (unsigned int *)malloc(len * sizeof(unsigned int)); if (temp_copy == NULL) return 0; memcpy(temp_copy, arr, len * sizeof(unsigned int)); // Verwendung der lokalen compare_helper Funktion qsort(temp_copy, len, sizeof(unsigned int), compare_helper); unsigned int unique_count = 0; unsigned int duplicate_value = 0; for (unsigned int i = 0; i < len; i++) { // Zählen der eindeutigen Werte if (i == 0 || temp_copy[i] != temp_copy[i-1]) { unique_count++; } // Identifizieren des Duplikats if (i > 0 && temp_copy[i] == temp_copy[i-1]) { duplicate_value = temp_copy[i]; } } ASSERT_TRUE(unique_count == len - 1, "Array sollte genau len-1 eindeutige Werte enthalten."); ASSERT_TRUE(duplicate_value != 0, "Es sollte genau ein Duplikat gefunden werden."); free(temp_copy); free(arr); return 1; } int test_createNumbers_edgeCases() { // 1. Test mit minimaler Länge (len=2) unsigned int len_min = 2; unsigned int *arr_min = createNumbers(len_min); ASSERT_TRUE(arr_min != NULL, "createNumbers sollte bei len=2 nicht NULL zurueckgeben."); ASSERT_TRUE(getDuplicate(arr_min, len_min) != 0, "Bei len=2 sollte ein Duplikat gefunden werden."); free(arr_min); // 2. Test mit len=0 unsigned int *arr_zero = createNumbers(0); ASSERT_TRUE(arr_zero == NULL, "createNumbers sollte bei len=0 NULL zurueckgeben."); // 3. Test mit größerer Länge (len=500) unsigned int len_large = 500; unsigned int *arr_large = createNumbers(len_large); ASSERT_TRUE(arr_large != NULL, "createNumbers sollte bei len=500 nicht NULL zurueckgeben."); unsigned int duplicate_val = getDuplicate(arr_large, len_large); ASSERT_TRUE(duplicate_val != 0, "Bei len=500 sollte ein Duplikat gefunden werden."); ASSERT_TRUE(count_occurrences(arr_large, len_large, duplicate_val) == 2, "Duplikat sollte genau 2-mal vorkommen."); free(arr_large); return 1; } int test_getDuplicate_findsDuplicate() { unsigned int arr1[] = {1, 5, 3, 5, 2}; unsigned int len1 = 5; unsigned int result1 = getDuplicate(arr1, len1); ASSERT_TRUE(result1 == 5, "Duplikat 5 sollte gefunden werden."); unsigned int arr2[] = {42, 1, 99, 1, 0}; unsigned int len2 = 5; unsigned int result2 = getDuplicate(arr2, len2); ASSERT_TRUE(result2 == 1, "Duplikat 1 sollte gefunden werden."); // Test mit Duplikat am Anfang/Ende unsigned int arr3[] = {10, 20, 30, 40, 10}; unsigned int len3 = 5; unsigned int result3 = getDuplicate(arr3, len3); ASSERT_TRUE(result3 == 10, "Duplikat 10 sollte gefunden werden."); return 1; } int test_getDuplicate_noDuplicateOrEdgeCases() { // 1. Kein Duplikat unsigned int arr1[] = {1, 2, 3, 4}; unsigned int len1 = 4; unsigned int result1 = getDuplicate(arr1, len1); ASSERT_TRUE(result1 == 0, "Kein Duplikat sollte 0 zurueckgeben."); // 2. Leeres Array unsigned int arr2[] = {}; unsigned int len2 = 0; unsigned int result2 = getDuplicate(arr2, len2); ASSERT_TRUE(result2 == 0, "Leeres Array sollte 0 zurueckgeben."); // 3. Array mit einem Element unsigned int arr3[] = {5}; unsigned int len3 = 1; unsigned int result3 = getDuplicate(arr3, len3); ASSERT_TRUE(result3 == 0, "Array mit einem Element sollte 0 zurueckgeben."); return 1; } // --- HAUPTFUNKTION (Test Runner) --- typedef int (*test_func)(void); struct { const char *name; test_func func; } tests[] = { {"test_createNumbers_basic", test_createNumbers_basic}, {"test_createNumbers_edgeCases", test_createNumbers_edgeCases}, {"test_getDuplicate_findsDuplicate", test_getDuplicate_findsDuplicate}, {"test_getDuplicate_noDuplicateOrEdgeCases", test_getDuplicate_noDuplicateOrEdgeCases}, }; int main(void) { int total_tests = sizeof(tests) / sizeof(tests[0]); int successful_tests = 0; printf("Starte %d Unit-Tests...\n", total_tests); printf("------------------------------------------\n"); for (int i = 0; i < total_tests; i++) { printf("Teste: %s ... ", tests[i].name); fflush(stdout); if (tests[i].func()) { printf("PASSED \n"); successful_tests++; } else { printf("FAILED \n"); } } printf("------------------------------------------\n"); if (successful_tests == total_tests) { printf("ERGEBNIS: ALLE %d TESTS ERFOLGREICH BESTANDEN.\n", total_tests); return EXIT_SUCCESS; } else { printf("ERGEBNIS: %d von %d TESTS FEHLGESCHLAGEN.\n", total_tests - successful_tests, total_tests); return EXIT_FAILURE; } }