Sta creando gli oggetti che ritieni di aver bisogno di essere ok in un primo test in TDD

15

Sono abbastanza nuovo per TDD e ho problemi durante la creazione del mio primo test quando viene prima di qualsiasi codice di implementazione. Senza alcuna struttura del codice di implementazione, sono libero di scrivere il mio primo test, ma lo voglio sempre, ma sembra sempre influenzato dal mio modo di pensare Java / OO sul problema.

Ad esempio nel mio Github ConwaysGameOfLifeExample il primo test che ho scritto (rule1_zeroNeighbours) ho iniziato creando un oggetto GameOfLife che non aveva è stato ancora implementato; chiamato un metodo set che non esisteva, un metodo step che non esisteva, un metodo get che non esisteva e quindi utilizzava un assert.

I test si sono evoluti nel momento in cui ho scritto più test e refactored, ma in origine era simile a questo:

@Test
public void rule1_zeroNeighbours()
{
    GameOfLife gameOfLife = new GameOfLife();
    gameOfLife.set(1, 1, true);
    gameOfLife.step();
    assertEquals(false, gameOfLife.get(1, 1));
}

Questo è strano visto che stavo forzando la progettazione dell'attuazione in base a come avevo deciso in questa fase iniziale di scrivere questo primo test.

Nel modo in cui capisci che TDD è ok? Mi sembra di seguire i principi TDD / XP in quanto i miei test e la mia implementazione si sono evoluti nel tempo con il refactoring, e quindi se questo progetto iniziale si fosse dimostrato inutile sarebbe stato aperto a cambiare, ma mi sembra di forzare una direzione sul soluzione iniziando in questo modo.

In quale altro modo le persone usano TDD? Avrei potuto passare attraverso più iterazioni di refactoring iniziando senza oggetti GameOfLife, solo primitive e metodi statici, ma sembra troppo inventato.

    
posta Encaitar 17.03.2015 - 13:07
fonte

6 risposte

9

This felt odd as I was forcing the design of the implementation based on how I had decided at this early stage to write this first test.

Penso che questo sia il punto chiave della tua domanda, che sia desiderabile o meno dipende dall'idea di codeninja che dovresti progettare in anticipo, quindi utilizzare TDD per completare l'implementazione, o l'idea di durron che i test dovrebbero essere coinvolti nella guida del design e dell'implementazione.

Penso che quale di questi preferisci (o dove ti trovi nel mezzo) sia qualcosa che devi scoprire come preferenza. È utile capire i pro e i contro di ciascun approccio. Probabilmente ce ne sono molti, ma direi che i principali sono:

Pro Upfront Design

  • Comunque un buon processo TDD è alla guida della progettazione, non è perfetto. TDing senza una destinazione concreta in mente a volte può finire in vicoli ciechi, e almeno alcuni di questi vicoli ciechi avrebbero potuto essere evitati con un po 'di pensiero iniziale su dove si vuole finire. Questo articolo del blog rende questo argomento usando l'esempio dei numeri romani kata, e ha un'implementazione finale piuttosto piacevole per mostra per questo.

Pro-guida alla progettazione di prova

  • Costruendo la tua implementazione attorno a un client del tuo codice (i tuoi test), ottieni YAGNI-aderenza praticamente gratis, purché non inizi a scrivere casi di test non necessari. Più in generale, ottieni un'API progettata attorno al suo utilizzo da parte di un consumatore, che in definitiva è ciò che desideri.

  • L'idea di disegnare un gruppo di diagrammi UML prima di scrivere qualsiasi codice e quindi semplicemente riempire gli spazi vuoti è carina, ma raramente realistica. Nel Codice Completo di Steve McConnell, il design è notoriamente descritto come un "problema malvagio", un problema che non puoi comprendere appieno senza prima risolverlo almeno parzialmente. Accoppiandolo con il fatto che il problema di fondo stesso può cambiare attraverso il cambiamento dei requisiti, e questo modello di design inizia a sentirsi un po 'senza speranza. Il test di guida ti consente di mordere solo una porzione di lavoro alla volta - nel design, non solo nell'implementazione - e sapere che, almeno per la durata di viraggio del rosso al verde, tale compito sarà comunque aggiornato e pertinente.

Per quanto riguarda il tuo esempio particolare, come dice durron, se hai seguito un approccio di guida del progetto scrivendo il test più semplice, consumando l'interfaccia minima possibile, probabilmente avresti un'interfaccia più semplice di quella in il tuo snippet di codice.

    
risposta data 17.03.2015 - 15:17
fonte
17

Per scrivere il test, in primo luogo, devi progettare l'API che implementerai. Hai già iniziato con il piede sbagliato scrivendo il test per creare l'oggetto intero GameOfLife e utilizzarlo per implementare il test.

Da Practical Unit Testing con JUnit e Mockito :

At first you might feel awkward for writing something which is not even there. It requires a slight change to your coding habits, but after some time you will come to see it is a great design opportunity. By writing tests first, you have a chance of creating an API that is convenient for a client to use. Your test is the first client of a newly born API. This is what TDD is really all about: the design of an API.

Il tuo test non è il tentativo di progettare un'API. Hai impostato un sistema stateful in cui tutte le funzionalità sono contenute all'interno della classe GameOfLife esterna.

Se dovessi scrivere questa applicazione, penserei invece ai pezzi che voglio costruire. Ad esempio, potrei creare una classe Cell , scrivere test per questo, prima di passare all'applicazione più grande. Creo sicuramente una classe per la struttura dei dati "infinita in ogni direzione" che è necessaria per implementare correttamente Conway e testarlo. Una volta fatto tutto, penserei di scrivere la classe generale che ha un metodo main e così via.

È facile sorvolare il passaggio "scrivi un test che fallisce". Ma scrivere il test fallito che funziona nel modo in cui lo si desidera è il nocciolo del TDD.

    
risposta data 17.03.2015 - 14:16
fonte
0

Non mi piacciono i test di livello di sistema scritti in java o C # per questo motivo. Guardate SpecFlow per c # o uno dei framework di test basati su Cucumber per java (forse JBehave). Quindi i tuoi test possono assomigliare più a questo.

Epuoimodificarelaprogettazionedell'oggettosenzadovermodificaretuttiitestdisistema.

(Itestdiunità"normali" sono ottimi quando si testano le singole classi.)

Quali sono le differenze tra i framework BDD per Java?

    
risposta data 17.03.2015 - 18:00
fonte
0

Ci sono diverse scuole di pensiero su questo.

Alcuni dicono: test non compilato è errore - vai a correggere scrivi il più piccolo codice di produzione disponibile.

Alcuni dicono: è OK scrivere test per prima cosa controlla se fa schifo (o no) e poi crea classi / metodi mancanti

Con il primo approccio sei davvero in un ciclo refact rosso-verde. Con il secondo si ha una panoramica un po 'più ampia di ciò che si vuole raggiungere.

Spetta a te scegliere il tuo modo di lavorare. Entrambi gli approcci sono validi.

    
risposta data 17.03.2015 - 13:33
fonte
0

Anche quando implemento qualcosa in un modo "hackerarlo insieme", penso ancora alle classi e ai passaggi che saranno coinvolti nell'intero programma. Quindi hai riflettuto su questo e hai scritto questi pensieri di design come test per primi: è fantastico!

Ora continua a ripetere l'implementazione per soddisfare questo test iniziale, quindi aggiungi altri test per migliorare ed estendere la progettazione.

Che cosa potrebbe aiutarti a utilizzare Cetriolo o simile per scrivere i tuoi test.

    
risposta data 17.03.2015 - 14:08
fonte
0

Prima di iniziare a scrivere i tuoi test, dovresti pensare a come progettare il tuo sistema. Dovresti passare una notevole quantità di tempo durante la fase di progettazione. Se l'hai fatto, non avrai questa confusione su TDD.

TDD è solo un approccio di sviluppo link: TDD
1. Aggiungi un test
2. Eseguire tutti i test e vedere se quello nuovo non riesce a 3. Scrivi un codice
4. Eseguire test
5. Codice del rifattatore
6. Ripeti

TDD ti aiuta a coprire tutte le funzionalità richieste che hai pianificato prima di iniziare a sviluppare il tuo software. link: Vantaggi

    
risposta data 17.03.2015 - 14:32
fonte

Leggi altre domande sui tag