main.c
Le langage C permet de manipuler des pointeurs sur fonctions. A titre d'exemple, voici un mini système d'exécution de batteries de tests unitaire.
Pour définir le contenu d'une batterie de tests, des pointeurs sur fonctions sont utilisés : ces fonctions doivent bien entendu respecter une signature bien
précise, cette signature étant décrite dans le type de pointeurs sur fonctions TestFunction
.
Ce premier fichier de code correspond à un exemple d'utilisation du framework de test. Notez que chaque fonctions de tests doit renvoyer un booléen : la valeur
true
signifie que le test s'est exécuté en succès et une valeur false
signifie, au contraire, que le test a échoué.
#include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include "TestFramework.h" bool test1( const char * testName ) { // TODO return true; } bool test2( const char * testName ) { // TODO return false; } // TODO ... int main() { TestFramework tester; addTestFunction( &tester, "Nom du premier test", test1 ); addTestFunction( &tester, "Nom de second test", test2 ); runTestSuite( &tester ); // Résultat de l'exécution du programme : // Run "Nom du premier test" Ok // Run "Nom de second test" Ko // ----------------------- // Run 2 tests // 1 test in success // 1 test in failure return EXIT_SUCCESS; }
main.c
Le second fichier correspond au fichier d'entête de définition du framework de test.
Il est notamment inclu par le fichier main.c
.
#ifndef TESTFRAMEWORK_H_ #define TESTFRAMEWORK_H_ #include <stdbool.h> #include <stddef.h> /* Defines a new typedef based on a function pointeur type. */ typedef bool (* TestFunction)( const char * ); typedef struct _ListNode { const char * testName; TestFunction fct; struct _ListNode * next; } ListNode; typedef struct { ListNode * first; } List; List createEmptyList(); void insertList( List * list, const char * testName, TestFunction fct ); void displayList( List * list ); void destroyList( List * list ); typedef struct { List functions; } TestFramework; //void addTestFunction( TestFramework * framework, const char * testName, bool (*fct)( const char * ) ); void addTestFunction( TestFramework * framework, const char * testName, TestFunction fct ); void runTestSuite( TestFramework * framework ); #endif /* TESTFRAMEWORK_H_ */
TestFramework.h
Enfin, voici l'implémentation de notre framework de test.
#include <assert.h> #include <stdio.h> #include "TestFramework.h" List createEmptyList() { List emptyList; emptyList.first = NULL; return emptyList; } /** * Caution: in our sample, the list must be ordered. */ void insertList( List * list, const char * testName, TestFunction fct ) { ListNode * toInsert = (ListNode *) malloc( sizeof( ListNode ) ); if ( list->first == NULL ) { list->first = toInsert; toInsert->testName = testName; toInsert->fct = fct; toInsert->next = NULL; return; } ListNode * current = list->first; while ( true ) { int compareResult = strcmp( testName, current->testName ); if ( compareResult < 0 ) { toInsert->testName = current->testName; toInsert->fct = current->fct; toInsert->next = current->next; current->testName = testName; current->fct = fct; current->next = toInsert; return; } if ( current->next == NULL ) { current->next = toInsert; toInsert->testName = testName; toInsert->fct = fct; toInsert->next = NULL; return; } current = current->next; } } void displayList( List * list ) { ListNode * current = list->first; while( current != NULL ) { printf( "\"%s\" -> ", current->testName ); current = current->next; } puts( "NULL\n" ); } void destroyList( List * list ) { ListNode * current = list->first; while( current != NULL ) { ListNode * next = current->next; free( current ); current = next; } list->first = NULL; } static bool testFrameworkIsInitialized = false; void addTestFunction( TestFramework * framework, const char * testName, TestFunction fct ) { if ( ! testFrameworkIsInitialized ) { framework->functions = createEmptyList(); testFrameworkIsInitialized = true; } insertList( &framework->functions, testName, fct ); } void runTestSuite( TestFramework * framework ) { size_t goodTests = 0; size_t badTests = 0; ListNode * current = framework->functions.first; while( current != NULL ) { const char * testName = current->testName; bool result = current->fct( testName ); if ( result ) goodTests++; else badTests++; printf( "Run %-30s %s\n", testName, result ? "Ok" : "Ko" ); current = current->next; } printf( "----------------------------------------------\n" ); printf( "Run %lu test(s)\n", goodTests+badTests ); printf( "\t%lu test(s) in success\n", goodTests ); printf( "\t%lu test(s) in failure\n", badTests ); destroyList( &framework->functions ); }
TestFramework.c
Améliorations / Corrections
Vous avez des améliorations (ou des corrections) à proposer pour ce document : je vous remerçie par avance de m'en faire part, cela m'aide à améliorer le site.
Emplacement :
Description des améliorations :