Debugging e Unit Testing
I programmatori inesperti tendono a fare debug riempiendo il codice sorgente di funzioni printf() per capire i valori delle variabili. Un approccio nettamente superiore è utilizzare un Debugger integrato nell’IDE (come Visual Studio o VS Code) o a riga di comando (come il leggendario GNU Debugger, GDB).
L’arte del Debugging
Section titled “L’arte del Debugging”Un debugger permette di arrestare il tempo mentre il programma è in esecuzione e ispezionare la memoria, senza modificare il codice per inserire continue stampe su schermo! I concetti chiave sono:
- Breakpoint (Punto di interruzione): Un segno rosso (o comando GDB come
break main.c:42) messo su una riga di codice. Quando l’esecuzione raggiunge quella riga, il programma si congela in pausa. - Ispezione Variabili (Locals / Autos / Watch): Mentre il programma è in pausa, il debugger ti mostra in una tabella (o tramite il comando GDB
print my_var) tutti i nomi delle variabili locali e il loro esatto valore in quel nanosecondo. - Single Step (Passo a passo): Ti permette di eseguire un’istruzione alla volta in GDB o nel tuo IDE.
- Step Over (GDB:
nexton): Esegue la riga corrente e passa alla successiva. Se la riga contiene una funzione, la esegue istantaneamente tutta in un colpo solo. - Step Into (GDB:
stepos): Se la riga corrente è la chiamata a una funzione, “entra” dentro la funzione per farti analizzare la sua logica interna passo-passo. - Step Out (GDB:
finish): Esegue il resto della funzione in cui ti trovi e si ferma subito dopo che questa ha fattoreturnal chiamante.
- Step Over (GDB:
Unit Testing
Section titled “Unit Testing”Una volta che hai debuggato una funzione con successo, non fermarti lì. Scrivi uno Unit Test!
Lo Unit Testing è un processo in cui si scrivono dei mini-programmi (spesso chiamati test suites) il cui unico scopo è testare automaticamente le singole funzioni della tua libreria passandogli input noti e verificando che l’output coincida con le aspettative.
I framework per il C e C++ più famosi sono Google Test (gtest), CUnit e Unity.
Esempio con Google Test (C++)
Section titled “Esempio con Google Test (C++)”Anche se Google Test è scritto in C++, è lo standard industriale per testare librerie scritte in C. Un test si definisce tramite macro come TEST ed EXPECT_EQ.
#include "gtest/gtest.h"
extern "C" { #include "mia_libreria_matematica.h" // Importiamo la funzione C da testare}
// Definiamo un blocco di testTEST(MatematicaSuite, TestSommaPositiva) { // Mi ASPETTO (EXPECT) che la funzione somma(2, 2) sia UGUALE (EQ) a 4. EXPECT_EQ(somma(2, 2), 4);
// Mi aspetto che la funzione restituisca esattamente 100 EXPECT_EQ(somma(99, 1), 100);}
int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); // Avvia l'esecuzione di tutti i TEST() definiti}💻 Esercizio Pratico
Section titled “💻 Esercizio Pratico”Esercitati a scrivere una logica corretta. Se fosse un unit test, chiameremmo questa funzione più volte verificando l’output! Modifica la funzione per ritornare il numero maggiore tra i due passati come argomento.