Quando scrivi il codice "reale" in TDD?

johnny 08/19/2017. 11 answers, 20.464 views
tdd

Tutti gli esempi che ho letto e visto sui video di formazione hanno esempi semplicistici. Ma cosa non vedo se come faccio il codice "reale" dopo che divento verde. Questa è la parte "Refactor"?

Se ho un oggetto abbastanza complesso con un metodo complesso, scrivo il mio test e il minimo indispensabile per farlo passare (dopo che fallisce per primo, Red). Quando torno indietro e scrivo il codice reale? E quanto codice reale scrivo prima di ripetere il test? Immagino che l'ultimo sia più intuito.

Edit: grazie a tutti coloro che hanno risposto Tutte le tue risposte mi hanno aiutato immensamente. Sembra che ci siano idee diverse su quello che stavo chiedendo o confuso, e forse c'è, ma quello che stavo chiedendo era, diciamo, che ho una domanda per costruire una scuola.

Nel mio design, ho un'architettura con cui voglio iniziare, User Story, così via e così via. Da qui, prendo quelle User Story e creo un test per testare User Story. L'utente dice, Abbiamo persone iscriversi per la scuola e pagare le tasse di registrazione. Quindi, penso a un modo per farlo fallire. In tal modo, progetto una classe di test per la classe X (forse Student), che fallirà. Quindi creo la classe "Studente". Forse "scuola" non lo so.

Ma, in ogni caso, il TD Design mi costringe a pensare attraverso la storia. Se riesco a far fallire un test, so perché fallisce, ma questo presuppone che io possa farlo passare. Riguarda la progettazione.

Parlo di ciò pensando a Ricorsione. La ricorsione non è un concetto difficile. Potrebbe essere più difficile tenerne traccia nella tua testa, ma in realtà, la parte più difficile è sapere, quando la ricorsione "si interrompe", quando fermarsi (la mia opinione, ovviamente.) Quindi devo pensare a cosa si ferma prima la Ricorsione. È solo un'analogia imperfetta e presuppone che ogni iterazione ricorsiva sia un "passaggio". Di nuovo, solo un'opinione.

In attuazione, la scuola è più difficile da vedere. I registri numerici e bancari sono "facili" nel senso che puoi usare l'aritmetica semplice. Riesco a vedere a + b e a restituire 0, ecc. Nel caso di un sistema di persone, devo riflettere più duramente su come implement . Ho il concetto di fallire, passare, refactoring (principalmente per lo studio e questa domanda).

Quello che non so è basato sulla mancanza di esperienza, secondo me. Non so come fallire l'iscrizione a un nuovo studente. Non so come fallire qualcuno che digita un cognome e viene salvato in un database. So come fare un + 1 per la matematica semplice, ma con entità come una persona, non so se sto solo testando per vedere se ottengo un ID univoco del database o qualcos'altro quando qualcuno inserisce un nome in un database o entrambi o nessuno dei due.

O forse questo dimostra che sono ancora confuso.

5 Comments
187 hobbs 07/25/2017
Dopo il TDD le persone tornano a casa per la notte.
14 Goyo 07/25/2017
Perché pensi che il codice che hai scritto non sia reale?
2 johnny 07/26/2017
@RubberDuck Più delle altre risposte. Sono sicuro che farò presto riferimento. È ancora un po 'estraneo, ma non ho intenzione di arrendermi. Quello che hai detto ha senso. Sto solo provando a farlo nel mio contesto o in una normale applicazione aziendale. Forse un sistema di inventario o simili. Devo considerarlo. Sono grato per il tuo tempo però. Grazie.
1 Edmund Reed 07/26/2017
Le risposte hanno già colpito il chiodo sulla testa, ma finché tutti i test sono passati e non è necessario alcun nuovo test / funzionalità, si può presumere che il codice che hai è finito, bar linting.
3 Borjab 07/26/2017
C'è un'aspirazione nella domanda che potrebbe essere problematica in "Ho un oggetto abbastanza complesso con un metodo complesso". In TDD scrivi prima i tuoi test in modo da iniziare con un codice abbastanza semplice. Ciò ti costringerà a codificare una struttura di test che dovrà essere modulare. Un comportamento così complesso verrà creato combinando oggetti più semplici. Se finisci con un oggetto o un metodo abbastanza complesso, allora è quando ti rifatti

11 Answers


RubberDuck 07/27/2017.

Se ho un oggetto abbastanza complesso con un metodo complesso, scrivo il mio test e il minimo indispensabile per farlo passare (dopo che fallisce per primo, Red). Quando torno indietro e scrivo il codice reale? E quanto codice reale scrivo prima di ripetere il test? Immagino che l'ultimo sia più intuito.

Non "vai indietro" e scrivi "codice reale". È tutto un codice reale. Quello che fai è tornare indietro e aggiungere un altro test che ti forces a change il codice per fare in modo che il nuovo test passi.

Quanto a quanto codice scrivi prima di ripetere il test? Nessuna. Scrivi zero codice senza un test fallito che ti forces a scrivere più codice.

Si noti il ​​modello?

Passiamo attraverso un altro semplice esempio nella speranza che sia d'aiuto.

 Assert.Equal("1", FizzBuzz(1)); 

Facile peazy.

 public String FizzBuzz(int n) {
    return 1.ToString();
} 

Non quello che chiameresti codice reale, giusto? Aggiungiamo un test che costringe un cambiamento.

 Assert.Equal("2", FizzBuzz(2)); 

Potremmo fare qualcosa di sciocco come if n == 1 , ma salveremo alla soluzione sana.

 public String FizzBuzz(int n) {
    return n.ToString();
} 

Freddo. Funzionerà per tutti i numeri non FizzBuzz. Qual è il prossimo input che costringerà il codice di produzione a cambiare?

 Assert.Equal("Fizz", FizzBuzz(3));

public String FizzBuzz(int n) {
    if (n == 3)
        return "Fizz";
    return n.ToString();
} 

E di nuovo. Scrivi un test che non passerà ancora.

 Assert.Equal("Fizz", FizzBuzz(6));

public String FizzBuzz(int n) {
    if (n % 3 == 0)
        return "Fizz";
    return n.ToString();
} 

E ora abbiamo coperto tutti i multipli di tre (che non sono anche multipli di cinque, lo annunceremo e torneremo).

Non abbiamo ancora scritto un test per "Buzz", quindi scriviamolo.

 Assert.Equal("Buzz", FizzBuzz(5));

public String FizzBuzz(int n) {
    if (n % 3 == 0)
        return "Fizz";
    if (n == 5)
        return "Buzz"
    return n.ToString();
} 

E ancora, sappiamo che c'è un altro caso che dobbiamo gestire.

 Assert.Equal("Buzz", FizzBuzz(10));

public String FizzBuzz(int n) {
    if (n % 3 == 0)
        return "Fizz";
    if (n % 5 == 0)
        return "Buzz"
    return n.ToString();
} 

E ora possiamo gestire tutti i multipli di 5 che non sono anche multipli di 3.

Fino a questo punto, abbiamo ignorato la fase di refactoring, ma vedo alcune duplicazioni. Puliamolo adesso.

 private bool isDivisibleBy(int divisor, int input) {
    return (input % divisor == 0);
}

public String FizzBuzz(int n) {
    if (isDivisibleBy(3, n))
        return "Fizz";
    if (isDivisibleBy(5, n))
        return "Buzz"
    return n.ToString();
} 

Freddo. Ora abbiamo rimosso la duplicazione e creato una funzione ben denominata. Qual è il prossimo test che possiamo scrivere che ci costringerà a cambiare il codice? Bene, abbiamo evitato il caso in cui il numero è divisibile sia con 3 che con 5. Scriviamolo ora.

 Assert.Equal("FizzBuzz", FizzBuzz(15));

public String FizzBuzz(int n) {
    if (isDivisibleBy(3, n) && isDivisibleBy(5, n))
        return "FizzBuzz";
    if (isDivisibleBy(3, n))
        return "Fizz";
    if (isDivisibleBy(5, n))
        return "Buzz"
    return n.ToString();
} 

I test passano, ma abbiamo più duplicazioni. Abbiamo delle opzioni, ma ho intenzione di applicare "Estrai la variabile locale" alcune volte in modo da eseguire il refactoring anziché riscrivere.

 public String FizzBuzz(int n) {

    var isDivisibleBy3 = isDivisibleBy(3, n);
    var isDivisibleBy5 = isDivisibleBy(5, n);

    if ( isDivisibleBy3 && isDivisibleBy5 )
        return "FizzBuzz";
    if ( isDivisibleBy3 )
        return "Fizz";
    if ( isDivisibleBy5 )
        return "Buzz"
    return n.ToString();
} 

E abbiamo coperto ogni input ragionevole, ma per quanto riguarda l'input unreasonable ? Cosa succede se passiamo 0 o un negativo? Scrivi quei casi di test.

 public String FizzBuzz(int n) {

    if (n < 1)
        throw new InvalidArgException("n must be >= 1);

    var isDivisibleBy3 = isDivisibleBy(3, n);
    var isDivisibleBy5 = isDivisibleBy(5, n);

    if ( isDivisibleBy3 && isDivisibleBy5 )
        return "FizzBuzz";
    if ( isDivisibleBy3 )
        return "Fizz";
    if ( isDivisibleBy5 )
        return "Buzz"
    return n.ToString();
} 

Sta iniziando a sembrare "codice reale"? Ancora più importante, a che punto ha smesso di essere "codice irreale" e transizione verso l'essere "reale"? È qualcosa su cui riflettere ...

Quindi, sono stato in grado di farlo semplicemente cercando un test che sapevo non sarebbe passato ad ogni passaggio, ma ho avuto molta pratica. Quando sono al lavoro, le cose non sono mai così semplici e potrei non sapere sempre quale test forzerà un cambiamento. A volte scrivo un test e sono sorpreso di vederlo già passato! Consiglio vivamente di prendere l'abitudine di creare una "Lista dei test" prima di iniziare. Questo elenco di test dovrebbe contenere tutti gli input "interessanti" che puoi immaginare. Potresti non usarli tutti e probabilmente aggiungerai dei casi man mano che andrai, ma questa lista serve da guida di marcia. La mia lista di test per FizzBuzz sarebbe simile a questa.

  • Negativo
  • Zero
  • Uno
  • Due
  • Tre
  • Quattro
  • Cinque
  • Sei (multiplo non banale di 3)
  • Nove (3 al quadrato)
  • Dieci (multiplo non banale di 5)
  • 15 (multipli di 3 e 5)
  • 30 (multiplo non banale di 3 e 5)
5 comments
3 maple_shaft♦ 07/27/2017
I commenti non sono per discussioni estese; questa conversazione è stata spostata in chat .
40 GManNickG 07/27/2017
A meno che non stia completamente fraintendendo questa risposta: "Potremmo fare qualcosa di sciocco come se n == 1, ma salveremo alla soluzione sana". - il tutto era sciocco. Se sai in anticipo, vuoi una funzione che <specifica>, scrivi test per <specifica> e salta la parte in cui scrivi le versioni che ovviamente falliscono <specifica>. Se trovi un bug in <specifica> allora sicuro: scrivi prima un test per verificare che puoi esercitarlo prima della correzione e osserva i passaggi di test dopo la correzione. Ma non c'è bisogno di simulare tutti questi passaggi intermedi.
15 user3791372 07/28/2017
I commenti che evidenziano i principali difetti in questa risposta e TDD in generale sono stati spostati in chat. Se stai pensando di utilizzare TDD, leggi la 'chat'. Sfortunatamente i commenti sulla "qualità" sono ora nascosti tra un carico di chat per i futuri studenti da leggere.
nbro 07/28/2017
Sarei più preciso riguardo al contenuto di questa "lista dei test", se volessi migliorare questa risposta. Vorrei parlare esplicitamente di "valori limite" e "partizionamento di classe".
2 hvd 07/30/2017
@GManNickG Credo che il punto sia ottenere la giusta quantità di test. Scrivendo i test in anticipo è facile perdere ciò che i casi speciali dovrebbero essere testati, portando a situazioni che non sono adeguatamente trattate nei test, o essenzialmente alla stessa situazione che è stata inutilmente coperta un sacco di volte nei test. Se puoi farlo senza questi passaggi intermedi, bene! Tuttavia non tutti possono farlo, è qualcosa che richiede pratica.

GenericJon 07/24/2017.

Il codice "reale" è il codice che scrivi per far passare il test. Really . È così semplice.

Quando le persone parlano di scrivere il minimo indispensabile per rendere il test verde, ciò significa solo che il tuo codice reale dovrebbe seguire il principio YAGNI .

L'idea della fase di refactoring è solo quella di ripulire ciò che hai scritto una volta che sei felice che soddisfi i requisiti.

Finché i test che scrivi in ​​realtà comprendono i tuoi requisiti di prodotto, una volta che passano, il codice è completo. Pensaci, se tutte le tue esigenze aziendali hanno un test e tutti questi test sono ecologici, che altro c'è da scrivere? (Va bene, nella vita reale non tendiamo ad avere una copertura di prova completa, ma la teoria è valida.)

5 comments
44 Derek Elkins 07/24/2017
I test unitari non possono effettivamente comprendere i requisiti del prodotto per requisiti relativamente insignificanti. Nella migliore delle ipotesi, campionano lo spazio input-output e l'idea è che tu (correttamente) si generalizzi allo spazio input-output completo. Naturalmente, il tuo codice potrebbe essere semplicemente un grande switch con un caso per ogni unit test che supererebbe tutti i test e fallirebbe per qualsiasi altro input.
8 Taemyr 07/25/2017
@DerekElkins TDD richiede test falliti. Test dell'unità non falliti.
6 jonrsharpe 07/25/2017
@DerekElkins è per questo che non scrivi solo i test unitari, e anche perché c'è un presupposto generale che stai cercando di creare qualcosa non solo falso!
35 Derek Elkins 07/25/2017
@jonrsharpe Con quella logica, non scriverò mai implementazioni banali. Ad esempio nell'esempio di FizzBuzz nella risposta di RubberDuck (che utilizza solo i test unitari), la prima implementazione chiaramente "semplicemente falsifica". La mia comprensione della domanda è esattamente questa dicotomia tra il codice di scrittura che tu sai essere incompleto e il codice che credi sinceramente implementerà il requisito, il "codice reale". Il mio "grande switch " era inteso come l'estremo logico di "scrivere il minimo indispensabile per rendere i test verdi". Considero la domanda dell'OP come: dove in TDD è il principio che evita questo grande switch ?
2 Luaan 07/25/2017
@GenericJon Questo è un po 'troppo ottimistico nella mia esperienza :) Per uno, ci sono persone che amano il lavoro ripetitivo senza cervello. Saranno più felici con una dichiarazione switch gigante che con un "processo decisionale complicato". E per perdere il lavoro, o avrebbero bisogno di qualcuno che li chiamasse per la tecnica (e hanno una buona prova che sta effettivamente perdendo le opportunità / i soldi della compagnia!), O fanno eccezionalmente male. Dopo aver preso in carico la manutenzione di molti di questi progetti, posso dire che è facile che un codice molto ingenuo duri per decenni, a patto che renda il cliente felice (e pagante).

Carl Raymond 07/24/2017.

La risposta breve è che il "codice reale" è il codice che fa passare il test. Se riesci a far passare il tuo test con qualcosa di diverso dal codice reale, aggiungi altri test!

Sono d'accordo sul fatto che molti tutorial su TDD sono semplicistici. Questo funziona contro di loro. Un test troppo semplice per un metodo che, per esempio, calcola 3 + 8 non ha davvero altra scelta che calcolare anche 3 + 8 e confrontare il risultato. Questo fa sembrare che si stia duplicando il codice dappertutto, e che il test sia inutile, un lavoro extra soggetto a errori.

Quando sei bravo a provare, questo ti informerà su come strutturi la tua applicazione e su come scrivi il tuo codice. Se hai difficoltà a trovare test utili e sensati, dovresti probabilmente ripensare il tuo design un po '. Un sistema ben progettato è facile da testare - il che significa che test facili da pensare sono facili da pensare e da implementare.

Quando scrivi i test per primi, guardali fallire e poi scrivi il codice che li fa passare, è una disciplina per garantire che tutto il tuo codice abbia test corrispondenti. Non seguo pedissequamente questa regola quando sto codificando; spesso scrivo prove dopo il fatto. Ma fare i primi test aiuta a mantenere la tua onestà. Con una certa esperienza, inizierai a notare quando ti stai codificando in un angolo, anche quando non stai scrivendo i test prima.

4 comments
6 Steve Jessop 07/26/2017
Personalmente, il test che avrei scritto sarebbe assertEqual(plus(3,8), 11) , non assertEqual(plus(3,8), my_test_implementation_of_addition(3,8)) . Per i casi più complessi, si cerca sempre un modo per dimostrare il risultato corretto, other than calcolare dinamicamente il risultato corretto nel test e controllare l'uguaglianza.
Steve Jessop 07/26/2017
Quindi, per un modo davvero stupido di farlo per questo esempio, potresti provare che plus(3,8) ha restituito il risultato corretto sottraendo 3 da esso, sottraendo 8 da quello, e verificando il risultato su 0. Questo è ovviamente equivalente a assertEqual(plus(3,8), 3+8) per essere un po 'assurdo, ma se il codice sotto test sta costruendo qualcosa di più complicato di un intero, allora prendere il risultato e controllare ogni parte per la correttezza è spesso l'approccio giusto In alternativa, qualcosa come for (i=0, j=10; i < 10; ++i, ++j) assertEqual(plus(i, 10), j)
Steve Jessop 07/26/2017
... dal momento che evita la grande paura, che è che quando si scrive il test faremo lo stesso errore sul tema "come aggiungere 10" che abbiamo fatto nel codice live. Quindi il test evita accuratamente di scrivere qualsiasi codice che aggiunga 10 a qualsiasi cosa, nel test che plus() può aggiungere 10 alle cose. Facciamo ancora affidamento sui valori del ciclo intiale verificati dal programmatore, ovviamente.
3 Warbo 07/28/2017
Voglio solo sottolineare che anche se stai scrivendo dei test dopo il fatto, è comunque una buona idea guardarli fallire; trova una parte del codice che sembra fondamentale per qualsiasi cosa tu stia lavorando, modificala un po '(ad esempio sostituisci un + con un - o qualsiasi altro), esegui i test e guardali fallire, annulla la modifica e guardali passare. Molte volte ho fatto questo, il test in realtà non fallisce, rendendolo peggio che inutile: non solo non sta testando nulla, mi sta dando la falsa fiducia che qualcosa sia stato testato!

Victor Cejudo 07/25/2017.

A volte alcuni esempi di TDD possono essere fuorvianti. Come altre persone hanno sottolineato prima, il codice che scrivi per far passare i test è il codice reale.

Ma non pensare che il codice reale appaia come una magia: è sbagliato. È necessaria una migliore comprensione di ciò che si desidera ottenere e quindi è necessario selezionare il test di conseguenza, a partire dai casi più semplici e dai casi limite.

Ad esempio, se hai bisogno di scrivere un lexer, inizi con una stringa vuota, poi con una serie di spazi bianchi, poi un numero, poi con un numero circondato da spazi bianchi, poi un numero sbagliato, ecc. Queste piccole trasformazioni ti porteranno a l'algoritmo giusto, ma non si passa dal caso più semplice a un caso altamente complesso scelto stupidamente per ottenere il codice reale.

Bob Martin lo spiega perfettamente qui .


CandiedOrange 07/25/2017.

La parte del refattore è pulita quando sei stanco e vuoi andare a casa.

Quando stai per aggiungere una feature, la parte refactor è ciò che cambi prima del prossimo test. Si rifatta il codice per fare spazio alla nuova funzione. Lo fai quando know quale sarà questa nuova funzionalità. Non quando lo stai solo immaginando.

Questo può essere semplice come rinominare GreetImpl in GreetWorld prima di creare una classe GreetMom (dopo aver aggiunto un test) per aggiungere una funzione che stamperà "Ciao mamma".


graeme 07/27/2017.

Ma il codice reale apparirebbe nella fase di refactoring della fase TDD. Cioè il codice che dovrebbe essere parte della versione finale.

I test dovrebbero essere eseguiti ogni volta che apporti una modifica.

Il motto del ciclo di vita TDD sarebbe: RED GREEN REFACTOR

RED : scrivi i test

GREEN : fai un tentativo onesto di ottenere un codice funzionale che superi i test il più rapidamente possibile: codice duplicato, variabili di nome oscuro come hack di altissimo livello, ecc.

REFACTOR : ripulire il codice, denominare correttamente le variabili. Asciugare il codice.

5 comments
5 mcottle 07/25/2017
So cosa stai dicendo riguardo alla fase "Verde" ma implica che i valori di ritorno del cablaggio duro per far passare i test potrebbero essere appropriati. Nella mia esperienza "Green" dovrebbe essere un onesto tentativo di rendere il codice funzionante per soddisfare il requisito, potrebbe non essere perfetto ma dovrebbe essere completo e "spedibile" come lo sviluppatore può gestire in un primo passaggio. Il refactoring è probabilmente fatto meglio qualche tempo dopo che hai fatto più sviluppo e i problemi con il primo passaggio diventano più evidenti e le opportunità di emergere.
graeme 07/25/2017
@mcottle considero questi tutti parte dello stesso compito. fatelo, quindi pulitelo. Ulteriori rifacimenti dovrebbero avvenire nel tempo, come parte di altri compiti.
1 Bryan Boettcher 07/25/2017
@mcottle: potresti essere sorpreso di quante implementazioni di un repository get-only possano essere valori codificati nella codebase. :)
6 Kaz 07/25/2017
Perché dovrei scrivere codice criptato e ripulirlo, quando riesco a sfornare un codice di qualità di produzione piacevole quasi quanto posso digitare? :)
1 Kaz 07/27/2017
@TimothyTruckle Che cosa succede se occorrono 50 minuti per trovare il cambiamento più semplice possibile, ma solo 5 per trovare il secondo cambiamento più semplice possibile? Andiamo con il secondo più semplice o continuiamo a cercare il più semplice?

Timothy Truckle 07/27/2017.

Quando scrivi il codice "reale" in TDD?

La fase red è dove write codice.

Nella fase di refactoring l'obiettivo principale è quello di delete codice.

Nella fase red fai qualsiasi cosa per far passare il test il as quick as possible e at any cost . Ignorerai completamente ciò che hai sentito di buone pratiche di codifica o di schemi di progettazione simili. Fare il test green è tutto ciò che conta.

Nella fase di refactoring ripulisci il casino che hai appena fatto. A questo punto, per prima cosa, verifica se il cambiamento appena apportato è il tipo più in alto nell'elenco delle priorità di trasformazione e se è possibile duplicare il codice è più probabile rimuoverlo applicando un motivo di progettazione.

Infine, si migliora la leggibilità rinominando gli identificatori e si estrae i magic numbers e / o le stringhe letterali in costanti.


Non è un refattore rosso, è un refact rosso-verde. - Rob Kinyon

Grazie per aver indicato questo.

Quindi è la fase green cui scrivi il real code

Nella fase red scrivi la executable specification ...

2 comments
Rob Kinyon 07/27/2017
Non è un refattore rosso, è un refact rosso-verde. Il "rosso" si prende la tua suite di test da verde (tutti i test passano) a rosso (un test non riesce). Il "verde" è il punto in cui si trascina la suite di test dal rosso (un test fallisce) al verde (tutti i test superano). Il "refactoring" è il punto in cui prendi il tuo codice e rendilo bello mentre passi tutti i test.
Timothy Truckle 07/27/2017
@RobKinyon Grazie, ha aggiornato la risposta.

Robert Andrzejuk 07/27/2017.

Stai scrivendo Real Code tutto il tempo.

Ad ogni passo Stai scrivendo il codice per soddisfare le condizioni che il tuo codice soddisferà per i futuri chiamanti del tuo codice (che potresti essere Tu o no ...).

Pensi di non scrivere codice ( real ) utile, perché in un momento potresti rifattorici.

Il codice di refactoring è il processo di ristrutturazione del codice informatico esistente che modifica il factoring, senza modificarne il comportamento esterno.

Ciò significa che anche se stai modificando il codice, le condizioni che il codice soddisfa, rimangono invariate. E i controlli ( tests ) che hai implementato per verificare il tuo codice sono già lì per verificare se le tue modifiche sono cambiate. Quindi il codice che hai scritto per tutto il tempo è lì, solo in un modo diverso.

Un'altra ragione Si potrebbe pensare che non è un codice reale, è che stai facendo esempi in cui il programma finale può già essere previsto da te. Questo è molto buono, poiché mostra che hai conoscenza del domain stai programmando.
Ma molte volte i programmatori si trovano in un domain che è new , a loro unknown . Non sanno quale sarà il risultato finale e TDD è una technique per scrivere i programmi passo dopo passo, documentando le nostre knowledge su come questo sistema dovrebbe funzionare e verificando che il nostro codice funzioni in questo modo.

Quando ho letto The Book (*) su TDD, per me la caratteristica più importante che spicca è stata la seguente: TODO list. Mi ha dimostrato che, TDD è anche una tecnica per aiutare gli sviluppatori a concentrarsi su una cosa alla volta. Quindi questa è anche una risposta alla tua domanda aboout How much Real code to write ? Direi abbastanza codice per concentrarsi su 1 cosa alla volta.

(*) "Test Driven Development: By Example" di Kent Beck

1 comments
2 Robert Andrzejuk 07/27/2017
"Test Driven Development: By Example" di Kent Beck

Zenilogix 07/31/2017.

Non stai scrivendo il codice per far fallire i test.

Scrivi i tuoi test per definire come dovrebbe essere il successo, che inizialmente dovrebbe fallire perché non hai ancora scritto il codice che passerà.

L'intero punto sulla scrittura di test inizialmente non validi è di fare due cose:

  1. Coprire tutti i casi: tutti i casi nominali, tutti i casi limite, ecc.
  2. Valida i tuoi test. Se le vedi sempre passare, come puoi essere sicuro che segnaleranno in modo affidabile un errore quando si verifica?

Il punto dietro il refattore rosso-verde è che scrivere i test corretti ti dà la sicurezza di sapere che il codice che hai scritto per superare i test è corretto e ti permette di rifattarti con la certezza che i tuoi test ti informeranno non appena qualcosa si rompe, quindi puoi immediatamente tornare indietro e sistemarlo.

Nella mia esperienza personale (C # /. NET), il puro test-first è un po 'un ideale irraggiungibile, perché non è possibile compilare una chiamata a un metodo che non esiste ancora. Quindi, "testare prima" riguarda in realtà la codifica delle interfacce e delle implementazioni di stubing, quindi la scrittura di test sugli stub (che inizialmente falliscono) fino a quando gli stub non sono stati sviluppati correttamente. Non scrivo mai "codice fallito", semplicemente costruendo da stub.


Zan Lynx 07/27/2017.

Penso che tu possa essere confuso tra unit test e test di integrazione. Credo che ci possano essere anche test di accettazione, ma questo dipende dal tuo processo.

Una volta che hai testato tutte le piccole "unità", le proverai tutte assemblate o "integrate". Di solito è un intero programma o libreria.

Nel codice che ho scritto l'integrazione testa una libreria con vari programmi di test che leggono i dati e li alimentano alla libreria, quindi controllano i risultati. Allora lo faccio con i thread. Poi lo faccio con thread e fork () nel mezzo. Quindi lo eseguo e uccido -9 dopo 2 secondi, quindi lo avvio e ne controllo la modalità di ripristino. Mi sono confuso. Lo torturo in tutti i modi.

Tutto ciò è ANCHE testato, ma non ho un display rosso / verde piuttosto per i risultati. Succede o io scavare alcune migliaia di righe di codice di errore per scoprire perché.

È qui che si verifica il "codice reale".

E ho pensato a questo, ma forse non sai quando dovresti essere finito a scrivere test unitari. Hai finito di scrivere dei test unitari quando i tuoi test esercitano tutto ciò che hai specificato che dovrebbe fare. A volte puoi perdere la cognizione di tutto ciò che riguarda la gestione degli errori e i casi limite, quindi potresti voler creare un bel gruppo di test di test di percorso felice che semplicemente attraversi le specifiche.

1 comments
Peter Mortensen 07/27/2017
(è = possessivo, è = "è" o "ha". Vedi per esempio How to Use Its and It's .)

user3791372 07/27/2017.

In risposta al titolo della domanda: "Quando scrivi il codice" reale "in TDD?", La risposta è: "quasi mai" o "molto lentamente".

Sembri uno studente, quindi risponderò come se lo consigli a uno studente.

Imparerai molte codifiche di "teorie" e "tecniche". Sono ottimi per passare il tempo su corsi studenteschi troppo cari, ma con pochissimi benefici per te che non puoi leggere in un libro in metà tempo.

Il compito di un programmatore è esclusivamente quello di produrre codice. Codice che funziona davvero bene. Questo è il motivo per cui tu, il codificatore pianifica il codice nella tua mente, sulla carta, in un'applicazione adatta, ecc. E prevedi di aggirare eventuali difetti / buchi in anticipo pensando logicamente e lateralmente prima della codifica.

Ma devi sapere come rompere la tua domanda per essere in grado di progettare codice decente. Ad esempio, se non si conosceva Little Bobby Table (xkcd 327), probabilmente non si sarebbero disinfettati gli input prima di lavorare con il database, quindi non si sarebbe in grado di proteggere i dati in base a tale concetto.

TDD è solo un flusso di lavoro progettato per minimizzare i bug nel tuo codice creando test di ciò che potrebbe andare storto prima di codificare la tua applicazione perché la codifica può diventare esponenzialmente difficile più codice introduci e dimentichi bug che avevi pensato una volta. Una volta che pensi di aver terminato la tua applicazione, esegui i test e il boom, speriamo che i bug vengano catturati dai test.

TDD non è - come alcuni credono - scrivere un test, farlo passare con un codice minimo, scrivere un altro test, ottenere quel passaggio con un codice minimo, ecc. Invece, è un modo per aiutarti a codificare con sicurezza. Questo ideale di codice di refactoring continuo per farlo funzionare con i test è idiota, ma è un concetto piacevole tra gli studenti perché li fa sentire bene quando aggiungono una nuova funzione e stanno ancora imparando come codificare ...

Per favore non cadere in questa trappola e vedere il tuo ruolo di codifica per quello che è - il compito di un programmatore è solo quello di produrre codice. Codice che funziona davvero bene. Ora, ricorda che sarai l'orologio come programmatore professionista e al tuo cliente non interesserà se hai scritto 100.000 asserzioni, o 0. Vogliono solo il codice che funzioni. Davvero bene, infatti.

5 comments
3 johnny 07/25/2017
Non sono nemmeno vicino a uno studente, ma leggo e cerco di applicare buone tecniche ed essere professionale. Quindi in questo senso, sono uno "studente". Faccio solo domande molto basilari perché è così che sono. Mi piace sapere esattamente perché sto facendo quello che sto facendo. Il nocciolo della questione. Se non lo capisco, non mi piace e comincio a fare domande. Ho bisogno di sapere perché, se ho intenzione di usarlo. TDD sembra intuitivamente buono in qualche modo come sapere cosa è necessario creare e pensare le cose attraverso, ma l'implementazione è stata difficile da capire. Penso di avere una comprensione migliore ora.
4 Sean Burton 07/27/2017
Queste sono le regole del TDD. Sei libero di scrivere il codice come preferisci, ma se non segui queste tre regole non stai facendo TDD.
2 user3791372 07/27/2017
"Regole" di una persona? TDD è un suggerimento per aiutarti a programmare, non una religione. È triste vedere così tante persone aderire a un'idea così tanto. Anche l'origine di TDD è controversa.
2 Alex 07/28/2017
@ user3791372 TDD è un processo molto rigido e chiaramente definito. Anche se molti pensano che sia solo "Fai un po 'di test quando stai programmando", non lo è. Proviamo a non mescolare i termini qui, questa domanda riguarda il processo TDD, non i test generali.

HighResolutionMusic.com - Download Hi-Res Songs

1 (G)I-DLE

POP/STARS flac

(G)I-DLE. 2018. Writer: Riot Music Team;Harloe.
2 Ariana Grande

​Thank U, Next flac

Ariana Grande. 2018. Writer: Crazy Mike;Scootie;Victoria Monét;Tayla Parx;TBHits;Ariana Grande.
3 Imagine Dragons

Bad Liar flac

Imagine Dragons. 2018. Writer: Jorgen Odegard;Daniel Platzman;Ben McKee;Wayne Sermon;Aja Volkman;Dan Reynolds.
4 Backstreet Boys

Chances flac

Backstreet Boys. 2018.
5 Clean Bandit

Baby flac

Clean Bandit. 2018. Writer: Jack Patterson;Kamille;Jason Evigan;Matthew Knott;Marina;Luis Fonsi.
6 BTS

Waste It On Me flac

BTS. 2018. Writer: Steve Aoki;Jeff Halavacs;Ryan Ogren;Michael Gazzo;Nate Cyphert;Sean Foreman;RM.
7 BlackPink

Kiss And Make Up flac

BlackPink. 2018. Writer: Soke;Kny Factory;Billboard;Chelcee Grimes;Teddy Park;Marc Vincent;Dua Lipa.
8 Lady Gaga

I'll Never Love Again flac

Lady Gaga. 2018. Writer: Benjamin Rice;Lady Gaga.
9 Kelly Clarkson

Never Enough flac

Kelly Clarkson. 2018. Writer: Benj Pasek;Justin Paul.
10 Fitz And The Tantrums

HandClap flac

Fitz And The Tantrums. 2017. Writer: Fitz And The Tantrums;Eric Frederic;Sam Hollander.
11 Little Mix

Told You So flac

Little Mix. 2018. Writer: Eyelar;MNEK;Raye.
12 Halsey

Without Me flac

Halsey. 2018. Writer: Halsey;Delacey;Louis Bell;Amy Allen;Justin Timberlake;Timbaland;Scott Storch.
13 Cher Lloyd

None Of My Business flac

Cher Lloyd. 2018. Writer: ​iamBADDLUCK;Alexsej Vlasenko;Kate Morgan;Henrik Meinke;Jonas Kalisch;Jeremy Chacon.
14 Bradley Cooper

Always Remember Us This Way flac

Bradley Cooper. 2018. Writer: Lady Gaga;Dave Cobb.
15 Calum Scott

No Matter What flac

Calum Scott. 2018. Writer: Toby Gad;Calum Scott.
16 Ashley Tisdale

Voices In My Head flac

Ashley Tisdale. 2018. Writer: John Feldmann;Ashley Tisdale.
17 Imagine Dragons

Machine flac

Imagine Dragons. 2018. Writer: Wayne Sermon;Daniel Platzman;Dan Reynolds;Ben McKee;Alex Da Kid.
18 Diplo

Close To Me flac

Diplo. 2018. Writer: Ellie Goulding;Savan Kotecha;Peter Svensson;Ilya;Swae Lee;Diplo.
19 Billie Eilish

When The Party's Over flac

Billie Eilish. 2018. Writer: Billie Eilish;FINNEAS.
20 Little Mix

Woman Like Me flac

Little Mix. 2018. Writer: Nicki Minaj;Steve Mac;Ed Sheeran;Jess Glynne.

Related questions

Hot questions

Language

Popular Tags