336 lines
9.1 KiB
C
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;
|
|
}
|
|
} |