Il tuo codice funziona? Ne sei sicuro? Quante volte hai aggiunto una feature e scoperto che quella vecchia si è rotta? Noi, di Meteora Web, lo vediamo tutti i giorni nei progetti che ci arrivano. Il Test Driven Development (TDD) non è una moda da startup californiane: è un metodo che ti fa risparmiare ore di debugging e notti insonni. E inizia sempre con un ciclo: rosso, verde, refactoring.
Il ciclo Red-Green-Refactor: come funziona davvero
Il TDD si basa su tre fasi, ripetute per ogni singola unità di funzionalità:
- Red: scrivi un test che fallisce. Ancora non hai implementato nulla, ma il test descrive il comportamento desiderato.
- Green: scrivi il minimo codice necessario per far passare il test. Non importa se è brutto o inefficiente. Pochi secondi, righe essenziali.
- Refactor: pulisci il codice mantenendo i test verdi. Rimuovi duplicazioni, migliori leggibilità, ottimizzi se serve.
Poi ripeti. Sempre. Ogni ciclo dura da pochi secondi a pochi minuti. Se il ciclo si allunga, stai sbagliando qualcosa.
Perché funziona
Il TDD forza a pensare al comportamento prima dell'implementazione. Non parti da "come scrivo questa classe", ma da "cosa deve fare". Il risultato? Codice più modulare, testato automaticamente e con meno dipendenze nascoste. Nei progetti che seguiamo, chi adotta TDD riduce i bug in produzione del 40-60% già dal primo sprint. E il tempo perso per scrivere test viene recuperato almeno tre volte durante il debugging.
Esempio pratico: una funzione di sconto per e-commerce
Immagina di dover implementare una funzione che applica uno sconto percentuale a un prezzo, arrotondando a due decimali. Partiamo dal test.
// File: tests/DiscountTest.php
use PHPUnit\Framework\TestCase;
class DiscountTest extends TestCase
{
public function test_applies_percentage_discount()
{
$price = 100.00;
$discount = 20; // 20%
$result = applyDiscount($price, $discount);
$this->assertEquals(80.00, $result);
}
}Eseguiamo il test: rosso. La funzione applyDiscount non esiste. Ora scriviamo il codice minimo per far passare il test.
// File: src/Discount.php
function applyDiscount(float $price, float $percent): float
{
return $price - ($price * $percent / 100);
}Test eseguito: verde. Ora refactoring: la funzione è semplice, ma potremmo arrotondare a due decimali, aggiungere controlli sui parametri, o estrarre una classe. Per ora basta. Poi aggiungiamo un altro test: sconto al 100% deve dare 0, sconto negativo? E così via, ciclo dopo ciclo.
Strumenti essenziali per TDD in produzione
Non basta scrivere test a mano. Devi integrarli nel flusso di lavoro. Ecco cosa usiamo nei nostri progetti:
PHPUnit (PHP), Jest (JavaScript/TypeScript), pytest (Python)
Ogni linguaggio ha il suo. Scegli quello standard e impara a usarlo da riga di comando. Con --watch esegui i test automaticamente a ogni salvataggio.
Coverage, ma con criterio
Non inseguire il 100%. Copri i percorsi critici: condizioni limite, errori, casi d'uso principali. Il resto arriva col tempo. Noi verifichiamo che ogni branch logico abbia almeno un test.
Continous Integration (CI)
I test devono partire a ogni push. Usa GitHub Actions, GitLab CI o Jenkins. Se il test fallisce, la pipeline si blocca. Nessuna eccezione. Sui server che configuriamo, anche il deploy automatico richiede test verdi.
Errori comuni (e come evitarli)
- Test troppo grandi: se un test verifica 10 comportamenti diversi, non sai cosa si è rotto. Ogni test deve coprire una singola unità logica.
- Saltare il refactoring: verde non significa finito. Senza pulizia il codice diventa un groviglio di if e duplicazioni. Il refactoring è parte integrante del ciclo.
- Test dipendenti dall'ordine di esecuzione: ogni test deve essere indipendente e isolato. Usa
setUpper resettare lo stato. - Mock eccessivo: mocka solo ciò che è esterno (API, database). Se mocki tutto, non stai testando il tuo codice, ma la tua capacità di mockare.
Integrare TDD in un progetto esistente
Non devi riscrivere tutto. Inizia dai moduli più instabili o critici. Aggiungi un test per ogni bug che trovi (Regression Testing). Man mano che tocchi il codice, estrai funzioni pure e coprile con test nuovi. Noi lo facciamo ogni volta che ereditiamo un progetto legacy: prima scriviamo test per i flussi che già funzionano, poi interveniamo.
La nostra esperienza sul campo
Abbiamo costruito una piattaforma proprietaria per gestire la presenza social di più clienti. Senza TDD, l'integrazione con le API di Instagram sarebbe stata un incubo. Invece, ogni chiamata API è stata testata con mock, e quando Facebook ha cambiato l'endpoint, abbiamo corretto due righe, non giorni di debug. Lo stesso vale per il sistema ERP di abbigliamento che gestiamo: le regole di sconto stagionali sono state sviluppate in TDD, e le modifiche arrivano senza rompere le liquidazioni.
Cosa fare adesso
- Installa il framework di test per il tuo linguaggio. PHP?
composer require --dev phpunit/phpunit - Scrivi il primo test per una funzione semplice che già esiste. Fallo fallire, poi fallo passare.
- Esegui i test automaticamente con
--watch. Abituati a vedere rosso e verde. - Aggiungi un test per ogni bug che trovi. Così il bug non tornerà.
- Leggi la documentazione ufficiale: PHPUnit o Jest.
Noi, di Meteora Web, lo ripetiamo sempre: un codice senza test è un debito tecnico che prima o poi tocca pagare con gli interessi. Meglio iniziare oggi con un piccolo ciclo rosso-verde-refactoring. Il fatturato del cliente ti ringrazierà.
Sponsored Protocol