info2Praktikum-DobleSpiel/Test_numbers.c
2025-12-12 14:33:45 +01:00

336 lines
9.1 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <time.h>
#include "numbers.h"
#define GREEN "\033[0;32m"
#define RED "\033[0;31m"
#define RESET "\033[0m"
#define BLUE "\033[0;34m"
int testsPassed = 0;
int testsFailed = 0;
void printTestResult(const char *testName, int passed)
{
if (passed)
{
printf(GREEN "[PASS]" RESET " %s\n", testName);
testsPassed++;
}
else
{
printf(RED "[FAIL]" RESET " %s\n", testName);
testsFailed++;
}
}
// Hilfsfunktion: Prüft ob eine Zahl im Array vorkommt
int countOccurrences(const unsigned int *array, unsigned int len, unsigned int value)
{
int count = 0;
for (unsigned int i = 0; i < len; i++)
{
if (array[i] == value)
count++;
}
return count;
}
// Hilfsfunktion: Prüft ob alle Zahlen im gültigen Bereich sind
int allNumbersInRange(const unsigned int *array, unsigned int len, unsigned int min, unsigned int max)
{
for (unsigned int i = 0; i < len; i++)
{
if (array[i] < min || array[i] > max)
return 0;
}
return 1;
}
// Test 1: createNumbers mit kleiner Anzahl
void test_create_numbers_small()
{
printf(BLUE "\n--- Test 1: createNumbers mit 5 Zahlen ---" RESET "\n");
unsigned int len = 5;
unsigned int *numbers = createNumbers(len);
printTestResult("createNumbers gibt nicht-NULL zurueck", numbers != NULL);
if (numbers != NULL)
{
// Alle Zahlen zwischen 1 und 2*len?
int inRange = allNumbersInRange(numbers, len, 1, 2 * len);
printTestResult("Alle Zahlen im Bereich [1, 10]", inRange);
// Genau ein Duplikat zählen
int duplicateCount = 0;
for (unsigned int i = 0; i < len; i++)
{
int occurrences = countOccurrences(numbers, len, numbers[i]);
if (occurrences == 2)
duplicateCount++;
}
// duplicateCount sollte 2 sein (2 mal die gleiche Zahl)
printTestResult("Genau ein Duplikat vorhanden", duplicateCount == 2);
free(numbers);
}
}
// Test 2: createNumbers mit mittlerer Anzahl
void test_create_numbers_medium()
{
printf(BLUE "\n--- Test 2: createNumbers mit 20 Zahlen ---" RESET "\n");
unsigned int len = 20;
unsigned int *numbers = createNumbers(len);
printTestResult("createNumbers(20) gibt nicht-NULL zurueck", numbers != NULL);
if (numbers != NULL)
{
int inRange = allNumbersInRange(numbers, len, 1, 2 * len);
printTestResult("Alle Zahlen im Bereich [1, 40]", inRange);
free(numbers);
}
}
// Test 3: createNumbers mit Minimum (3 Zahlen)
void test_create_numbers_minimum()
{
printf(BLUE "\n--- Test 3: createNumbers mit Minimum (3 Zahlen) ---" RESET "\n");
unsigned int len = 3;
unsigned int *numbers = createNumbers(len);
printTestResult("createNumbers(3) funktioniert", numbers != NULL);
if (numbers != NULL)
{
int inRange = allNumbersInRange(numbers, len, 1, 2 * len);
printTestResult("Alle Zahlen im Bereich [1, 6]", inRange);
free(numbers);
}
}
// Test 4: createNumbers mit größerer Anzahl
void test_create_numbers_large()
{
printf(BLUE "\n--- Test 4: createNumbers mit 100 Zahlen ---" RESET "\n");
unsigned int len = 100;
unsigned int *numbers = createNumbers(len);
printTestResult("createNumbers(100) gibt nicht-NULL zurueck", numbers != NULL);
if (numbers != NULL)
{
int inRange = allNumbersInRange(numbers, len, 1, 2 * len);
printTestResult("Alle Zahlen im Bereich [1, 200]", inRange);
free(numbers);
}
}
// Test 5: getDuplicate findet das Duplikat
void test_get_duplicate_finds_duplicate()
{
printf(BLUE "\n--- Test 5: getDuplicate findet Duplikat ---" RESET "\n");
// Manuelles Test-Array mit bekanntem Duplikat
unsigned int testArray[] = {5, 12, 7, 3, 12, 9};
unsigned int len = 6;
unsigned int duplicate = getDuplicate(testArray, len);
printTestResult("getDuplicate findet korrektes Duplikat (12)", duplicate == 12);
}
// Test 6: getDuplicate mit sortiertem Array
void test_get_duplicate_sorted()
{
printf(BLUE "\n--- Test 6: getDuplicate mit sortiertem Array ---" RESET "\n");
unsigned int testArray[] = {1, 2, 3, 3, 4, 5};
unsigned int len = 6;
unsigned int duplicate = getDuplicate(testArray, len);
printTestResult("getDuplicate funktioniert mit sortiertem Array", duplicate == 3);
}
// Test 7: getDuplicate mit unsortiertem Array
void test_get_duplicate_unsorted()
{
printf(BLUE "\n--- Test 7: getDuplicate mit unsortiertem Array ---" RESET "\n");
unsigned int testArray[] = {42, 17, 8, 99, 3, 42, 55};
unsigned int len = 7;
unsigned int duplicate = getDuplicate(testArray, len);
printTestResult("getDuplicate funktioniert mit unsortiertem Array", duplicate == 42);
}
// Test 8: Integration - createNumbers und getDuplicate
void test_integration_create_and_get()
{
printf(BLUE "\n--- Test 8: Integration createNumbers + getDuplicate ---" RESET "\n");
int allCorrect = 1;
// Teste mehrmals mit verschiedenen Größen
unsigned int sizes[] = {5, 10, 20, 50};
for (int i = 0; i < 4; i++)
{
unsigned int len = sizes[i];
unsigned int *numbers = createNumbers(len);
if (numbers == NULL)
{
allCorrect = 0;
break;
}
unsigned int duplicate = getDuplicate(numbers, len);
// Prüfe ob das gefundene Duplikat tatsächlich 2x vorkommt
int occurrences = countOccurrences(numbers, len, duplicate);
if (duplicate == 0 || occurrences != 2)
{
printf(" Fehler bei len=%u: duplicate=%u, occurrences=%d\n", len, duplicate, occurrences);
allCorrect = 0;
}
free(numbers);
}
printTestResult("Integration funktioniert fuer verschiedene Groessen", allCorrect);
}
// Test 9: Fehlerbehandlung - NULL-Pointer
void test_get_duplicate_null()
{
printf(BLUE "\n--- Test 9: Fehlerbehandlung NULL-Pointer ---" RESET "\n");
unsigned int result = getDuplicate(NULL, 10);
printTestResult("getDuplicate(NULL) gibt 0 zurueck", result == 0);
}
// Test 10: Fehlerbehandlung - Zu kleine Länge
void test_get_duplicate_too_small()
{
printf(BLUE "\n--- Test 10: Fehlerbehandlung zu kleine Laenge ---" RESET "\n");
unsigned int testArray[] = {42};
unsigned int result = getDuplicate(testArray, 1);
printTestResult("getDuplicate mit len=1 gibt 0 zurueck", result == 0);
}
// Test 11: Eindeutigkeit - Verschiedene Runs erzeugen verschiedene Arrays
void test_randomness()
{
printf(BLUE "\n--- Test 11: Zufaelligkeit ---" RESET "\n");
unsigned int len = 10;
unsigned int *numbers1 = createNumbers(len);
unsigned int *numbers2 = createNumbers(len);
if (numbers1 == NULL || numbers2 == NULL)
{
printTestResult("Arrays konnten erstellt werden", 0);
free(numbers1);
free(numbers2);
return;
}
// Prüfe ob Arrays unterschiedlich sind
int different = 0;
for (unsigned int i = 0; i < len; i++)
{
if (numbers1[i] != numbers2[i])
{
different = 1;
break;
}
}
printTestResult("Zwei Aufrufe erzeugen unterschiedliche Arrays", different);
free(numbers1);
free(numbers2);
}
// Test 12: Stress-Test
void test_stress()
{
printf(BLUE "\n--- Test 12: Stress-Test (500 Zahlen) ---" RESET "\n");
unsigned int len = 500;
unsigned int *numbers = createNumbers(len);
printTestResult("createNumbers(500) erfolgreich", numbers != NULL);
if (numbers != NULL)
{
unsigned int duplicate = getDuplicate(numbers, len);
int occurrences = countOccurrences(numbers, len, duplicate);
printTestResult("getDuplicate findet Duplikat in grossem Array", occurrences == 2);
free(numbers);
}
}
int main()
{
// Zufallsgenerator EINMAL zu Beginn initialisieren
srand(time(NULL));
printf("\n");
printf("+----------------------------------------------+\n");
printf("| NUMBERS UNIT TESTS |\n");
printf("+----------------------------------------------+\n");
test_create_numbers_small();
test_create_numbers_medium();
test_create_numbers_minimum();
test_create_numbers_large();
test_get_duplicate_finds_duplicate();
test_get_duplicate_sorted();
test_get_duplicate_unsorted();
test_integration_create_and_get();
test_get_duplicate_null();
test_get_duplicate_too_small();
test_randomness();
test_stress();
printf("\n");
printf("+----------------------------------------------+\n");
printf("| TEST ZUSAMMENFASSUNG |\n");
printf("+----------------------------------------------+\n");
printf(GREEN "Tests bestanden: %d" RESET "\n", testsPassed);
printf(RED "Tests fehlgeschlagen: %d" RESET "\n", testsFailed);
printf("Gesamt: %d\n", testsPassed + testsFailed);
if (testsFailed == 0)
{
printf(GREEN "\n==> Alle Tests erfolgreich!\n" RESET);
return EXIT_SUCCESS;
}
else
{
printf(RED "\n==> Einige Tests sind fehlgeschlagen!\n" RESET);
return EXIT_FAILURE;
}
}