Come utilizzare i test unitari quando si utilizza BDD?


17

Sto cercando di capire BDD. Ho letto alcuni articoli e, come ho capito, BDD è "il prossimo passo" di TDD. Lo dico perché trovo entrambi molto simili e, come ho potuto leggere in questo articolo , BDD è nato come un miglioramento rispetto a TDD. Fantastico, mi piace davvero l'idea.

C'è un punto pratico che non capisco, c'è un file .feature in cui il BA scriverà tutto il comportamento previsto in cui il sistema avrebbe. Come BA, non ha idea di come sia costruito il sistema, quindi scriveremo qualcosa del genere:

+ Scenario 1: l'account è in credito +

Dato che l'account è in credito

E la carta è valida

E il distributore contiene contanti

Quando il cliente richiede contanti

Quindi assicurarsi che il conto sia addebitato e assicurarsi che venga erogato denaro

E assicurati che la carta sia restituita

Ok, questo è fantastico, ma ci sono molte parti del sistema che collaboreranno affinché ciò accada (pensate a Account obj, Dispenser obj, Customer obj e così via). Per me questo sembra un test di integrazione.

Mi piacerebbe avere test unitari. Come testare il codice che controlla se il distributore ha denaro? O che il denaro viene erogato? O che il conto viene addebitato quando richiesto? Come posso combinare i test unitari con i test "BA Created"?


Ecco a cosa servono beffe e tronconi: isolare le parti in prova.
Robert Harvey,

Scusa, non capisco. Vuoi dire che dovrei deridere il distributore? Come lo testerei?
JSBach,

Quando testate il distributore, prendete in giro l'account, la carta e il cliente.
Robert Harvey,

3
Perché vuoi combinare unit test e "BA ha creato test"? Utilizzare TDD come tecnica per creare unit test per singole parti del software e aggiungere test aggiuntivi per testare i requisiti dal punto di vista della BA (chiamare questi ultimi test di integrazione, se lo si desidera). Dove vedi una contraddizione?
Doc Brown,

@DocBrown: Per "emergere naturalmente", intendo dire che alcuni TDD credono che un progetto software emergerà naturalmente dai test unitari come "refactor rosso-verde". In The Whiteboard si svolgono conversazioni in chat su questa domanda .
Robert Harvey,

Risposte:


27

Lo sviluppo guidato dal comportamento e lo sviluppo guidato dal test sono gratuiti, ma non si sostituiscono a vicenda.

Il modo in cui "si comporta" l'applicazione è descritto nei test di accettazione, che secondo BDD sarebbero le caratteristiche e gli scenari scritti in Cucumber.

I dettagli grintosi di come funziona ogni piccolo componente sono descritti nei Test delle unità. I risultati dei Test unitari supportano gli scenari che scrivi in ​​Cetriolo.

Immagina il processo per la costruzione di un'auto.

Innanzitutto, il team del prodotto fornisce le proprie idee e alla fine le riduce a scenari di utilizzo:

Scenario: Starting the car
    Given I am standing in front of the drivers door
    When I open the door
    Then the door should lift up DeLorean-style (yeah, baby!)
    When I get into the car
    And turn the key
    Then the engine roars to life

So che questo scenario sembra un po 'sciocco, ma è un requisito di alto livello, incentrato sul prodotto e sull'utente finale. Basta aprire la porta, girare la chiave e avviare il motore comporta MOLTI componenti diversi che lavorano insieme. Questo test non è sufficiente per assicurarsi che il veicolo funzioni correttamente. Devi testare il motorino di avviamento, la batteria, l'alternatore, la chiave, l'interruttore di accensione --- e l'elenco continua --- solo per salire in macchina e avviarlo. Ognuno di questi componenti ha bisogno dei propri test.

Lo scenario sopra è un test "Big Picture". Ogni componente del veicolo necessita di test "Small Picture" per assicurarsi che funzionino correttamente nel complesso.

La costruzione e il test del software sono gli stessi per molti aspetti. Si progetta dall'alto verso il basso, quindi si costruisce dal basso verso l'alto. Perché una porta che si solleva se non riesci nemmeno ad avviare il motore? Perché un antipasto se non hai la batteria?

Il team del prodotto presenterà i test di accettazione e li perfezionerà in Cetriolo. Questo ti dà il "quadro generale". Ora spetta al team di progettazione progettare i componenti corretti e il modo in cui interagiscono, quindi testarli separatamente --- questi sono i test delle unità.

Una volta superati i test unitari, inizia a implementare gli scenari Cetriolo. Una volta che questi sono passati, hai consegnato ciò che il team del prodotto ha chiesto.


C'è un modo per collegare quei test "Big Picture" con i test "Small Picture"? Voglio dire, quando le funzionalità cambiano ufficialmente (diciamo uno scenario di cetriolo che cambia), c'è un modo per mappare quella modifica ai test di fascia bassa (diciamo test junit che sono per quel particolare scenario di cetriolo)?
Srikanth,

Puoi avere metodi di supporto e asserzioni personalizzate condivise tra i tuoi test "quadro generale" e "quadro piccolo", ma molto probabilmente comporteranno una configurazione diversa per testare specifiche unità di codice.
Nick McCurdy,

[...] che secondo BDD sarebbero le Caratteristiche e gli Scenari scritti in Cetriolo. Stai fondendo principi e strumenti.
jub0bs,

Bene, Ok, il testo è un po 'fuori, ma il punto è che il comportamento di un'applicazione è catturato nelle caratteristiche e negli scenari.
Greg Burghardt,

9

Sto cercando di capire BDD. Ho letto alcuni articoli e, come ho capito, BDD è "il prossimo passo" di TDD. Lo dico perché trovo entrambi molto simili e, come ho potuto leggere in questo articolo, BDD è nato come un miglioramento rispetto a TDD.

In realtà, no, BDD non è "il prossimo passo" da TDD. Si è TDD. O più precisamente, è una riformulazione del TDD.

I creatori di BDD hanno notato che il principale ostacolo alla comprensione del fatto che TDD non riguarda i test ma le specifiche comportamentali era che tutta la terminologia TDD riguarda i test e non le specifiche comportamentali. È come cercare di non pensare a un elefante rosa quando qualcuno ti dice "cerca di non pensare a un elefante rosa", tranne con l'ulteriore complicazione di essere in una stanza piena di elefanti rosa e un ragazzo che urla costantemente "elefante rosa, rosa elefante, elefante rosa "nel tuo orecchio.

Quindi, hanno riformulato TDD in termini di specifiche comportamentali. "Test" e "casi di test" ora sono "esempi", "unità" sono "comportamenti", "asserzioni" sono "aspettative" e così via.

Tuttavia, la metodologia è sempre la stessa. Inizi con un test di accettazione (intendo "funzione"), ingrandisci un test di unità (intendo "esempio"), riduci lo zoom, ecc.

Mi piacerebbe avere test unitari. Come testare il codice che controlla se il distributore ha denaro? O che il denaro viene erogato? O che il conto viene addebitato quando richiesto? Come posso mescolare i test unitari con i test "BA Created"?

Allo stesso modo in TDD. Puoi scrivere le tue funzioni e i tuoi esempi in diversi framework (ad esempio Cucumber e RSpec) o anche in lingue diverse (ad esempio scrivere esempi per un progetto C in C e funzionalità in FIT / Fitnesse), puoi utilizzare un singolo framework di funzionalità per entrambi ( ad es. scrivere esempi e funzionalità in Cucumber) oppure è possibile utilizzare un singolo esempio di framework per entrambi (ad es. scrivere entrambi in RSpec). Non è nemmeno necessario utilizzare un framework.

Un esempio di TDD-done-right (che è identico a BDD) utilizzando solo un singolo framework è JUnit stesso, che contiene una combinazione di unit test (esempi) e test funzionali / di integrazione (caratteristiche), tutti scritti in JUnit stesso.

Credo che Kent Beck lo definisca "zoom". Inizia ad alto livello, quindi "ingrandisci" i dettagli, quindi torna indietro.


1

Disclaimer: non sono un esperto di BDD, ma provo a darti il ​​mio punto di vista sull'articolo a cui ti sei collegato.

TDD è una tecnica di implementazione: prima scrivi un test, quindi implementa il metodo, esegui il test, il refactor e aggiungi ulteriori test per lo stesso metodo o per un nuovo metodo. TDD in realtà non definisce alcuna regola su come scegliere i nomi di classe o metodo, dipende da te. TDD inoltre non ti dice "quando hai finito".

Quindi ogni volta che scrivi un test per un nuovo metodo, devi scegliere un nome per il metodo - e quello è il punto in cui entra in gioco BDD. Scegliendo i nomi dei metodi usando i termini commerciali dallo scenario sopra, e scegliendoli in un modo che descriva il comportamento della tua classe, stai facendo BDD. Ogni volta che ti chiedi "devo aggiungere ulteriori test", puoi guardare gli scenari forniti dal tuo BA e controllare se hai implementato completamente tutte le parti necessarie. In caso contrario, dovrai aggiungere altri test.

L'autore dell'articolo suggerisce anche di utilizzare uno schema di denominazione più legato al comportamento quando sceglie i nomi dei test, per questo motivo suggerisce di sostituire JUnit con uno strumento che non si basa su uno schema di denominazione in cui ogni caso di test deve iniziare con il nome "test". Anche se non conosco JBehave, penso che sia la principale differenza tra quello strumento e Junit.

Inoltre, gli scenari BDD costituiranno anche un modello per i test di integrazione, che in genere si aggiungeranno dopo aver definito i nomi dei metodi da TDD e dopo aver aggiunto un numero ragionevole di test unitari.

Quindi, per quanto ne so, TDD è uno strumento che puoi usare come parte di BDD e BDD ti aiuta a scrivere i test giusti e dare loro nomi migliori.


Per prima cosa, Junit supporta qualsiasi nome per i test; devi solo usare un'annotazione @Test. Tuttavia, potrebbe non averlo fatto nel 2003.
soru,

@soru Nel 2003 ha effettivamente imposto la parola "test".
Lunivore,

L'autore dell'articolo è Dan North, che ha avuto l'idea in primo luogo. Una delle cose che ha notato è che la parola "test" ci spinge a passare alla verifica della nostra implementazione (dominio della soluzione) mentre in realtà, esplorare e definire i test dovrebbe davvero farci rimanere nel dominio del problema. Dan ha descritto BDD come "ciò che TDD doveva essere". Leggi questo per maggiori informazioni: dannorth.net/2012/05/31/bdd-is-like-tdd-if
Lunivore
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.