Given-When-Then: cos'è, struttura degli scenari ed esempi

Autore: IT Sectr Pubblicato: 2026-04-10 Tempo di lettura: 8 min

Given-When-Then è un modello strutturale per descrivere scenari di test, preso in prestito dal BDD dal domain-driven design e adattato per Behaviour-Driven Development. Il formato divide lo scenario in tre parti logiche: precondizioni (Given), azione (When) e risultato atteso (Then). Secondo Martin Fowler (2023), Given-When-Then non è solo un formato di test, ma uno strumento di pensiero che disciplina l'analisi dei requisiti e la progettazione degli scenari prima dell'inizio dell'implementazione.

Punti chiave

  • Given-When-Then — modello di descrizione di scenari in tre blocchi: contesto, azione, risultato
  • Given imposta lo stato iniziale del sistema e i dati prima di eseguire l'azione sotto test
  • When descrive l'evento o l'azione che attiva la logica sotto test
  • Then verifica le modifiche attese allo stato o ai valori restituiti
  • Arrange-Act-Assert — equivalente di Given-When-Then nei test unitari, ma senza orientamento al linguaggio di business

Cos'è Given-When-Then?

Given-When-Then è un modello di descrizione del comportamento, formulato per la prima volta da Dan North nel 2006 come parte della metodologia Behavior-Driven Development. Il modello risolve il problema delle descrizioni non strutturate degli scenari di test, che spesso contengono un misto di precondizioni, azioni e verifiche in ordine arbitrario.

L'idea principale del modello è la separazione delle responsabilità tra tre blocchi. Ogni blocco è responsabile di un solo aspetto dello scenario: stato prima, evento durante e verifica dopo. Questo rende lo scenario leggibile, verificabile e automatizzabile. Secondo uno studio degli sviluppatori del framework Cucumber (2024), gli scenari che seguono rigorosamente il modello Given-When-Then richiedono il 42% in meno di tempo per essere compresi da un nuovo membro del team.

Origine del modello

Dan North ha preso in prestito l'idea della struttura in tre parti dalla formulazione di test in TDD e dalla metodologia Test-by-Example (creata da Brian Marick). Marick propose di descrivere i requisiti attraverso esempi (examples) che fungono contemporaneamente da test. Given-When-Then ha formalizzato questa idea, trasformando esempi non strutturati in un modello ripetibile.

Ambito di applicazione

Il modello Given-When-Then non si applica solo negli scenari BDD con Gherkin, ma anche nei test unitari comuni con JUnit, XCTest e altri framework. I commenti nel codice che dividono il test in tre blocchi sono una pratica comune per migliorare la leggibilità della base di test. Google raccomanda questo approccio nel suo libro «Software Engineering at Google» (2020).

Struttura dei tre blocchi

Ogni blocco di Given-When-Then ha una semantica strettamente definita e regole di compilazione. La violazione di queste regole produce scenari difficili da automatizzare o comprendere.

Given: precondizioni

Il blocco Given descrive lo stato del sistema prima di eseguire l'azione sotto test. Include: oggetti esistenti (utente, ordine, impostazioni), stati attivi (autenticato, connesso alla rete) e valori iniziali dei dati. Ogni Given deve essere verificabile — se lo stato del sistema non corrisponde a Given, lo scenario deve essere saltato o l'ambiente di test preparato in anticipo.

When: azione

Il blocco When descrive l'unico evento che innesca il comportamento sotto test. Può essere una chiamata a un metodo, un clic su un pulsante, la ricezione di una notifica o di una risposta dal server. La regola chiave è un When per scenario. Se è necessario verificare una sequenza di azioni, creare scenari separati, non una catena di When.

kotlin
// Given: creiamo i dati di test
val user = User(email = "test@example.com", balance = 500.0)
val product = Product(price = 150.0)

// When: eseguiamo l'azione
val result = PurchaseUseCase().buy(user, product)

// Then: verifichiamo il risultato
assertEquals(PurchaseResult.Success, result)
assertEquals(350.0, user.balance)

Then: risultato atteso

Il blocco Then verifica che il sistema sia passato allo stato atteso. Ciò include: valori restituiti, modifiche allo stato degli oggetti, chiamate a servizi esterni (tramite verifica di mock) e modifiche all'interfaccia utente. Ogni blocco Then può contenere più verifiche, ma tutte si riferiscono a una singola azione.

Given-When-Then e Arrange-Act-Assert

Given-When-Then e Arrange-Act-Assert (AAA) sono due varianti dello stesso modello in tre parti, ma con diversi pubblici di destinazione. Comprendere le loro differenze aiuta a scegliere il formato giusto per ogni attività.

AspettoGiven-When-ThenArrange-Act-Assert
OrigineBDD, analisi di businessTest unitari
LinguaggioNaturale (Gherkin)Codice (Kotlin, Swift, Java)
PubblicoIntero team + clienteSviluppatori
Livello di dettaglioAlto livelloDettagliato
AutomazioneCucumber, SpecFlowJUnit, XCTest, Mockito

Quando usare Given-When-Then

Il modello Given-When-Then è ottimale per scenari discussi con il cliente o l'analista: criteri di accettazione delle funzionalità, casi d'uso, verifiche di regressione. La sintassi Gherkin consente di scrivere questi scenari senza conoscenze di programmazione.

Quando usare Arrange-Act-Assert

Arrange-Act-Assert è la scelta naturale per i test unitari che verificano un metodo o una classe specifica. Il formato AAA non richiede framework aggiuntivi e funziona in qualsiasi linguaggio di programmazione. Per lo sviluppo iOS, Apple raccomanda AAA nella documentazione XCTest (2024).

Esempi di scenari in Kotlin

Vediamo esempi pratici di Given-When-Then in Kotlin per un'applicazione Android. Il primo esempio è un test del carrello della spesa con MockK. Il secondo è un test della logica di notifiche push.

Esempio 1: carrello della spesa

kotlin
class CartTest {
    fun `apply discount when total exceeds threshold`() {
        // Given
        val cart = Cart()
        cart.addItem(Item("Laptop", price = 1000.0))
        cart.addItem(Item("Mouse", price = 50.0))
        val discount = DiscountCalculator(0.1)

        // When
        val total = discount.applyIfEligible(cart)

        // Then
        assertEquals(945.0, total)
        assertTrue("Discount was not applied", total < 1050.0)
    }
}

Esempio 2: notifiche push con coroutine

Il secondo esempio dimostra Given-When-Then con codice asincrono. Qui Given imposta lo stato di Firebase Cloud Messaging, When — la ricezione di una notifica push, Then — la verifica dell'elaborazione.

kotlin
class PushNotificationTest {
    fun `handle push notification when app in background`() = runTest {
        // Given
        val prefs = mockk<SharedPreferences>()
        every { prefs.getString("token", null) } returns "fcm-token-abc"
        val handler = PushHandler(prefs)

        // When
        val data = RemoteMessage().apply {
            putData("type", "order_update")
            putData("order_id", "123")
        }
        val result = handler.handleNotification(data)

        // Then
        assertEquals(NotificationAction.OpenOrder("123"), result)
    }
}

Esempio 3: scenario Gherkin per l'autenticazione

Il terzo esempio è uno scenario BDD in Gherkin che mostra Given-When-Then nel contesto dei test di accettazione:

gherkin
Feature: User Authorization
  Scenario: User cannot login with expired token
    Given the user has an expired refresh token
    When they try to access the protected profile screen
    Then they should see the login screen
    And the app should clear all cached data

Migliori pratiche per scrivere scenari

L'applicazione efficace di Given-When-Then richiede il rispetto di diverse pratiche consolidate. Esse garantiscono leggibilità, manutenibilità e automazione degli scenari.

Un When per scenario

Regola rigorosa: uno scenario — un'azione. Se è necessario verificare una sequenza di più When, creare più scenari in cui il risultato del precedente diventa precondizione del successivo. Questo rende lo scenario atomico e comprensibile.

Evitare dati concreti in Given

Given deve descrivere l'essenza, non numeri concreti. Invece di «Given l'utente Ivanov con saldo di 500 rubli» — «Given un utente con saldo sufficiente». I dati concreti vengono spostati in Scenario Outline con una tabella di Examples. Questo rende lo scenario universale e riutilizzabile.

  • Scrivere Then come asserzioni misurabili — «l'utente dovrebbe vedere la schermata di login», non «l'utente dovrebbe essere reindirizzato»
  • Usare And per passaggi dello stesso tipo — se sono necessari più Given, combinarli con And, non creare un secondo Given
  • Non mescolare livelli di astrazione — Given-When-Then deve essere allo stesso livello: o di business o tecnico, ma non misto
  • Documentare il motivo dello scenario — un commento all'inizio del file .feature con la descrizione della regola di business aiuta il contesto

Given-When-Then nella pipeline CI/CD

L'integrazione degli scenari Given-When-Then nella pipeline di integrazione continua li trasforma da documentazione in protezione contro le regressioni. Ogni merge request in un progetto mobile esegue automaticamente gli scenari BDD e blocca l'unione se almeno uno scenario fallisce.

Esecuzione automatica degli scenari

Gli scenari BDD con Cucumber per Android vengono eseguiti tramite il compito Gradle ./gradlew cucumber. Per iOS (Quick/Nimble) — tramite xcodebuild test. Nei sistemi CI (GitHub Actions, GitLab CI, Bitrise), i test BDD vengono eseguiti su emulatori o dispositivi reali. Il report viene generato in formato HTML comprensibile per i manager: scenari verdi — superati, rossi — fallimento con indicazione del passo.

Documentazione vivente nel repository

I file .feature sono memorizzati nel repository accanto al codice e passano attraverso una revisione del codice. L'analista crea una merge request con nuovi scenari prima dell'inizio dello sviluppo (BDD-first). Lo sviluppatore scrive le definizioni dei passi e l'implementazione per far diventare verdi questi scenari. Quando tutti gli scenari passano — la funzionalità è pronta. Questo approccio, descritto nel libro di Gojko Adzic «Specification by Example» (2011), trasforma i requisiti in un artefatto eseguibile.

Domande frequenti

Given-When-Then è la stessa cosa di Arrange-Act-Assert?

Strutturalmente sì, è lo stesso modello in tre parti. La differenza sta nel pubblico: Given-When-Then è orientato al linguaggio di business e usato in BDD con Gherkin, mentre Arrange-Act-Assert è un formato tecnico per test unitari. La scelta dipende dal contesto e dal team.

Quante verifiche può contenere il blocco Then?

Non c'è limite, ma si raccomanda non più di 3–5 verifiche per Then. Se ci sono più verifiche, probabilmente lo scenario sta controllando troppe cose in una singola azione. Suddividetelo in più scenari con diversi Then.

È obbligatorio scrivere Given-When-Then in Gherkin?

No. Il modello può essere utilizzato in qualsiasi framework di test, semplicemente dividendo il test con commenti o righe vuote in tre blocchi. Gherkin è necessario solo se gli scenari sono scritti in formato .feature per Cucumber o SpecFlow.

Cosa fare con precondizioni lunghe in Given?

Si raccomanda di estrarre le precondizioni ripetitive in Background (Gherkin) o metodi @Before (JUnit). Se le precondizioni sono complesse, utilizzare il pattern Builder per creare dati di test. Questo mantiene Given breve e leggibile.

Il blocco When può essere vuoto?

No. When è un blocco obbligatorio che descrive l'azione. Se lo scenario verifica solo uno stato senza azione (ad esempio, «al caricamento dell'applicazione i dati dovrebbero essere memorizzati nella cache»), When descrive il trigger: «quando l'applicazione viene avviata».

Riepilogo

  • Given-When-Then — modello in tre parti per descrivere scenari: precondizione, azione, risultato atteso
  • Given imposta il contesto e lo stato iniziale, When — l'unica azione, Then — la verifica del risultato
  • Arrange-Act-Assert e Given-When-Then sono lo stesso modello con pubblico e livello di astrazione diversi
  • Il modello si applica in BDD (Gherkin, Cucumber) e nei test unitari comuni (JUnit, XCTest) tramite commenti
  • Regola chiave: un When per scenario — ogni azione deve essere verificata separatamente
  • Le precondizioni ripetitive vengono estratte in Background o metodi @Before per ridurre la duplicazione
  • Scenario Outline con una tabella di Examples permette di parametrizzare Given-When-Then con diversi set di dati senza duplicare il codice

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche