Guida completa a Unit Test, Integration Test e TDD
Test in C#: scrivere codice affidabile con unit test, integration test e TDD
๐ Introduzione
Nello sviluppo software, uno degli aspetti più trascurati (ma cruciali) è la qualità del codice. Troppo spesso ci si concentra sull’aggiungere nuove funzionalità il più velocemente possibile, trascurando la domanda più importante: "Funziona davvero come dovrebbe?"
Qui entrano in gioco i test automatici, fondamentali per lo sviluppo moderno. In C# e .NET, la scrittura dei test non solo è semplice, ma è parte integrante del ciclo di vita di un progetto professionale.
In questo articolo ti mostrerò:
Perché scrivere test in C#
Quali sono le tipologie più comuni
Un esempio concreto con xUnit
Come organizzare i test nel tuo progetto
Best practice ed errori da evitare
Un'introduzione al Test Driven Development (TDD)
๐ฏ Perché scrivere test automatici?
1. Eviti bug e regressioni
Un codice senza test è un terreno minato. Una modifica in una parte dell'app può rompere funzionalità altrove, senza che nessuno se ne accorga. I test fungono da rete di sicurezza.
2. Migliori la qualità del software
Quando scrivi test, sei costretto a pensare al comportamento atteso. Questo porta automaticamente a scrivere codice più pulito, modulare e leggibile.
3. Accelera lo sviluppo a lungo termine
Molti pensano che scrivere test rallenti lo sviluppo. Falso. Dopo un primo investimento iniziale, i test permettono modifiche rapide e sicure, riducendo tempi di debugging.
4. Faciliti il lavoro in team
I test sono documentazione vivente: raccontano come il codice dovrebbe comportarsi. Quando più sviluppatori lavorano su un progetto, questo diventa essenziale.
๐ง Tipologie di test in C#
๐งช Unit Test
Testano una singola unità di codice (un metodo, una funzione). Sono isolati, veloci e affidabili. Non interagiscono con il database, file system o API.
Esempio: testare che un metodo
Somma(int a, int b)ritorni il valore corretto.
๐ Integration Test
Verificano l’integrazione tra componenti: ad esempio tra una repository e il database. Sono più lenti, ma simulano comportamenti reali.
Esempio: verificare che un controller MVC salvi correttamente un record nel database.
๐งญ End-to-End (E2E)
Simulano l’intero comportamento dell’applicazione: dalla UI al database. Si usano spesso strumenti come Selenium, Playwright o Puppeteer.
โ๏ธ Esempio pratico con xUnit
Supponiamo di avere una semplice classe:
public class Calcolatrice { public int Somma(int a, int b) => a + b; public int Divisione(int a, int b) { if (b == 0) throw new DivideByZeroException("Divisore non può essere zero."); return a / b; } }
Ecco come possiamo testarla con xUnit:
public class CalcolatriceTests { [Fact] public void Somma_RitornaRisultatoCorretto() { var calc = new Calcolatrice(); var result = calc.Somma(3, 4); Assert.Equal(7, result); } [Fact] public void Divisione_PerZero_LanciaEccezione() { var calc = new Calcolatrice(); Assert.Throws<DivideByZeroException>(() => calc.Divisione(10, 0)); } }
๐ Come organizzare i test nel tuo progetto
Di solito, si crea un progetto separato:
MyProject/ โ โโโ MyProject.Core/ โโโ MyProject.API/ โโโ MyProject.Tests/
Ogni test segue la struttura AAA:
Arrange – preparo i dati
Act – eseguo l’azione
Assert – verifico il risultato
๐งฐ Tool e framework consigliati
xUnit – il più moderno e leggero, ideale per .NET Core.
NUnit – supporta test parametrizzati e più flessibilità.
MSTest – ufficiale Microsoft, integrato in Visual Studio.
Per i mock, consiglio:
Moq– potente e intuitivoAutoFixture– per generare oggetti random con valori realistici
โ Best Practice
Scrivi test per ogni classe di business
Dai ai test nomi descrittivi (es:
Calcolatrice_SommaDueNumeri_RisultatoCorretto)Testa anche i casi limite ed eccezioni
Mantieni i test veloci: niente accessi al database in un unit test
Integra i test nel CI/CD (GitHub Actions, Azure DevOps, ecc.)
โ Errori da evitare
Scrivere test fragili (dipendenti dall’orario o dal contenuto del database)
Fare test duplicati (es. testare lo stesso metodo in dieci modi inutili)
Testare l’infrastruttura invece della logica di business
Non eseguire i test regolarmente
๐ Test Driven Development (TDD)
Una menzione speciale merita il Test Driven Development.
Nel TDD, segui questo ciclo:
โ๏ธ Scrivi un test (che fallisce)
๐ง Scrivi il codice minimo per farlo passare
๐งน Refactoring del codice
Questo approccio forza una progettazione più chiara e modulare.
๐ Conclusioni
Se vuoi davvero scrivere codice professionale, affidabile e manutenibile, i test non sono un optional. Sono un investimento.
Nel mio lavoro, ogni modulo viene coperto da test:
per evitare regressioni
per garantire coerenza
per documentare il comportamento del software
Scrivere test non è tempo perso. È tempo risparmiato in futuro.