Vai al contenuto
SDETRole
SDETRole

Glossario · Fondamenti del testing

Unit test (test unitario)

In inglese: Unit test

Detto anche: test unitario, test unitari, unit testing, test di unità

Definizione

Test automatico che verifica una piccola porzione di codice, come una funzione o una classe, in isolamento da database, rete e altri servizi.

Uno unit test (test unitario) mette alla prova una piccola unità di codice, di solito una funzione, un metodo o una classe, e verifica il suo output o comportamento per determinati input. Gira in memoria, senza database reali, chiamate HTTP o file system, quindi impiega millisecondi e fallisce per un solo motivo preciso. Gli unit test formano la base della piramide dei test e di solito vengono scritti dagli sviluppatori insieme al codice.

Esempio (JUnit 5, Java 21)

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;

class DiscountCalculatorTest {

    private final DiscountCalculator calculator = new DiscountCalculator();

    @ParameterizedTest
    @CsvSource({ "99.99, 0.00", "100.00, 10.00", "250.00, 25.00" })
    void appliesTenPercentFromOneHundred(double total, double expected) {
        assertEquals(expected, calculator.discountFor(total), 0.001);
    }

    @Test
    void rejectsNegativeTotals() {
        assertThrows(IllegalArgumentException.class, () -> calculator.discountFor(-1));
    }
}

I test parametrizzati richiedono l’artifact junit-jupiter-params, incluso nella dipendenza aggregata junit-jupiter. (Il codice che gestisce denaro reale dovrebbe usare BigDecimal invece di double; qui è tenuto semplice.)

Cosa rende buono uno unit test

  • Veloce e deterministico. Niente sleep, orologi, casualità o rete. Inietta un Clock fisso invece di chiamare LocalDate.now().
  • Isolato. Le dipendenze vengono sostituite con test double quando renderebbero il test lento o imprevedibile.
  • Un comportamento per test, con un nome che lo dichiara, così un fallimento si spiega da solo.
  • Testa il comportamento, non l’implementazione. Verifica output ed effetti osservabili, non metodi privati, così il refactoring non rompe i test.

Unit test e test di integrazione

Uno unit test verifica la tua logica con tutto il resto sostituito. Un test di integrazione verifica che componenti reali funzionino insieme: il tuo repository con un database reale, il tuo client con un servizio reale (o in container). Gli unit test intercettano gli errori di logica a basso costo; i test di integrazione intercettano errori di collegamento, configurazione, serializzazione e query che negli unit test spariscono dietro ai mock. Una suite fatta solo di unit test può essere tutta verde mentre l’applicazione non riesce nemmeno ad avviarsi.

Come si definisce una “unità”

Non esiste una risposta universale. Alcuni team considerano unità una singola classe e mockano tutti i collaboratori. Altri considerano unità un piccolo gruppo di classi che implementa un comportamento e sostituiscono solo ciò che attraversa un confine di processo. Il secondo stile tende a produrre test meno fragili durante il refactoring.

Scrivi per cercare in tutto SDETRole.

Ricerca full-text con Pagefind · funziona nel tuo browser Apri la pagina di ricerca →