it-swarm.it

Perché il TDD non è più popolare nelle università?

Di recente, una persona qui ha posto una domanda di base su come calcolare in Python tutte le permutazioni degli elementi da un elenco. Come per la maggior parte delle domande poste dagli studenti, non ho fornito il codice sorgente effettivo in la mia risposta, ma piuttosto ha spiegato come affrontare il problema, che essenzialmente è finito in una presentazione di base dello sviluppo guidato dai test.

Pensando al problema stesso, mi sono ricordato di tutti i problemi simili che dovevo risolvere quando studiavo programmazione all'università. Non ci è mai stato insegnato lo sviluppo guidato dai test, né alcun metodo comparabile, ma ci è stato comunque chiesto costantemente di scrivere algoritmi che ordinano elementi da un elenco, o risolvere puzzle di Towers of Hanoi, ecc. Né sembrano tutti gli studenti che arrivano su SoftwareEngineering.SE per sapere come TDD (Test Driven Development) li aiuterebbe a risolvere i problemi che gli vengono dati: se lo fossero, avrebbero formulato le loro domande in modo molto diverso.

Il fatto è che, senza TDD, tutti questi problemi sono davvero piuttosto impegnativi. Mi considero uno sviluppatore professionista, ma passerei comunque un po 'di tempo a scrivere un algoritmo di ordinamento di elenchi senza TDD, se richiesto, e sarei quasi all'oscuro se mi chiedessero di calcolare tutte le permutazioni degli elementi in un elenco, ancora senza usando TDD. Con TDD, d'altra parte, ho risolto il problema delle permutazioni in pochi minuti quando scrivevo la risposta allo studente.

Qual è il motivo per cui il TDD non viene insegnato affatto o almeno molto tardi nelle università? In altre parole, sarebbe problematico spiegare l'approccio TDD prima di chiedere agli studenti di scrivere algoritmi di ordinamento delle liste e cose simili?


Seguendo le osservazioni in due delle domande:

Nella tua domanda, sembri presentare TDD come un "dispositivo di risoluzione dei problemi" [...] In passato, TDD è stato presentato come un "meccanismo di scoperta della soluzione", ma anche Bob Martin (il principale avvocato di TDD) ammette che è necessario apportare una notevole quantità di conoscenze precedenti alla tecnica.

e specialmente:

Sono curioso di sapere perché pensi che TDD renda più facile un problematico algoritmo con una specifica ben definita.

Trovo necessario spiegare un po 'di più ciò che, secondo me, è così magico riguardo al TDD quando si tratta di risolvere i problemi.

Al liceo e all'università, non avevo tecniche specifiche per risolvere i problemi, e questo valeva sia per la programmazione che per la matematica. In retrospettiva, suppongo che una di queste tecniche sia quella di rivedere l'attuale/ultima lezione/lezione e cercare il rapporto con l'esercizio. Se la lezione riguarda gli integrali, ci sono possibilità che il problema che l'insegnante ha chiesto di risolvere richieda l'uso degli integrali. Se la lezione riguardava la ricorsione, ci sono possibilità che il puzzle dato agli studenti possa essere risolto usando la ricorsione. Sono anche sicuro che ci sono approcci ben formalizzati per risolvere i problemi in matematica e quegli approcci possono essere applicati anche alla programmazione; tuttavia, non ne ho mai imparato nessuno.

Ciò significa che, in pratica, il mio approccio era semplicemente quello di risolvere il problema, cercando di indovinare come dovrebbe essere risolto. Allora, se mi avessero dato la sfida di generare permutazioni di elementi da un elenco, non avrei iniziato con un elenco vuoto come input, ma piuttosto un esempio illustrativo, come [4, 9, 2], cercando di capire perché ci sono sei possibili permutazioni e come posso generarle attraverso il codice. Da lì, ho bisogno di molte riflessioni per trovare un modo possibile per risolvere il problema. Questo è essenzialmente ciò che l'autore nel domanda originale ha fatto, finendo per usare random. Allo stesso modo, quando ero uno studente, nessun altro studente della mia età iniziava con []: tutto tornerebbe immediatamente al caso con due o tre elementi, e poi rimarrebbe bloccato per mezz'ora, a volte finendo con un codice che non viene compilato o non viene eseguito.

L'approccio TDD, per me, sembra essere controintuitivo. Voglio dire, funziona molto bene, ma non avrei mai capito da solo, prima di leggere alcuni articoli su TDD, che (1) dovrei iniziare con il caso più semplice, (2) scrivere il test prima di scrivere il codice, e (3 ) mai Rush, cercando di soddisfare diversi scenari nel codice. Guardando come pensano i programmatori principianti, ho l'impressione di non essere il solo a trovarlo controintuitivo. Credo che possa essere più intuitivo per i programmatori che hanno una buona conoscenza di un linguaggio funzionale. Suppongo che in Haskell, ad esempio, sarebbe naturale gestire il problema delle permutazioni considerando prima un caso di un elenco vuoto, quindi un caso di un elenco con un elemento e quindi un caso di un elenco di più elementi. Nei linguaggi in cui sono possibili algoritmi ricorsivi, ma non così naturali come in Haskell, tale approccio è tuttavia molto meno naturale, a meno che, naturalmente, non si pratichi TDD.

123
Arseni Mourzenko

Sono un insegnante di programmazione part-time in un college della comunità locale.

Il primo corso che viene insegnato in questo college è Java Programming and Algorithms. Questo è un corso che inizia con cicli e condizioni di base e termina con eredità, polimorfismo e un'introduzione alle collezioni. Tutto in un semestre, per gli studenti che non hanno mai scritto una riga di codice prima, un'attività che è completamente esotica per la maggior parte di loro.

Sono stato invitato una volta in un comitato di revisione del curriculum. Il consiglio ha identificato una serie di problemi con il curriculum CS del college:

  1. Troppi linguaggi di programmazione insegnati.
  2. Nessun corso sul ciclo di vita dello sviluppo software.
  3. Nessun corso di database.
  4. Difficoltà nel far trasferire i crediti alle università statali e locali, in parte perché queste scuole non riescono a concordare una definizione uniforme per i termini "Informatica", "Informatica" e "Ingegneria del software".

Il mio consiglio per loro? Aggiungi una classe capstone di due semestri al curriculum in cui gli studenti possono scrivere un'applicazione full-stack, un corso che coprirà l'intero ciclo di vita dello sviluppo del software dalla raccolta dei requisiti alla distribuzione. Ciò li renderebbe reperibili presso i datori di lavoro locali (a livello di apprendista).

Allora, dove si inserisce TDD in tutto questo? Onestamente non lo so.

Nella tua domanda, sembri presentare TDD come un "dispositivo di risoluzione dei problemi"; Vedo TDD principalmente come un modo per migliorare la progettazione e la testabilità del codice. In passato, TDD è stato presentato come un "meccanismo di scoperta della soluzione", ma anche Bob Martin (il principale sostenitore di TDD) ammette che è necessario apportare una notevole quantità di conoscenze precedenti alla tecnica.

In altre parole, devi ancora sapere come risolvere prima i problemi nel codice. TDD ti spinge nella giusta direzione generale rispetto alle specifiche di progettazione del software. Questo lo rende un corso di livello superiore, non di livello inferiore.

135
Robert Harvey

Prima di tutto, dobbiamo fondamentalmente distinguere tra Informatica e Ingegneria del software . (E forse in misura minore tra Software Engineering e Programmazione o "Coding".)

Come ha affermato uno dei miei professori CS: se hai bisogno di una tastiera, non stai facendo CS.

TDD è una pratica di ingegneria del software. Non ha molta relazione con l'Informatica. Quindi, se stai chiedendo perché gli studenti CS non imparano il TDD, è perché il TDD non ha molto a che fare con il CS.

Ora, Ingegneria del Software, che è un bollitore completamente diverso di pesce. Sono molto d'accordo sul fatto che TDD debba essere insegnato lì. Avevo una lezione di ingegneria del software (90 minuti a settimana per un semestre) e in questa classe abbiamo appreso Waterfall, V-Model, RUP, CMM, CASE , RAD, Spirale, Iterativo e probabilmente altre cose che ho dimenticato. Sicuramente, ci sarebbe stato spazio per spremere in TDD, specialmente se lo si integra con il resto dei corsi e si applica TDD a tutti i compiti e compiti in tutti i corsi in cui è richiesta la programmazione.

Ad essere sinceri, tuttavia, nel mio caso, il Manifesto Agile non era ancora stato scritto e TDD era una tecnica di nicchia oscura.

Se dai un'occhiata al mio preferito personale per insegnare programmazione, How To Design Programs , scoprirai che insegnano molto all'inizio che le funzioni dovrebbero venire con esempi di utilizzo e solo leggermente più tardi, il libro introduce test di unità automatizzati e suggerisce che quegli esempi di utilizzo dovrebbero essere scritti sotto forma di test. Insegnano anche che gli esempi di utilizzo e quelle che chiamano "dichiarazioni di scopo" (puoi considerarlo come la riga di riepilogo di un commento JavaDoc) dovrebbero essere scritti prima del codice.

Non insegnano esplicitamente TDD (hanno la loro metodologia), ma questo è almeno un po 'vicino. HtDP è progettato per insegnare agli studenti delle scuole superiori in meno di un anno, quindi penso che sia più che fattibile insegnarlo in un solo semestre all'università.

Ad essere onesti, tuttavia, sarebbe già una grande vittoria per gli studenti semplicemente insegnati che possono effettivamente eseguire il codice che hanno scritto con input diversi. (In altre parole, una forma grezza di test manuali.) Sono sorpreso dalla frequenza con cui gli studenti non sono in grado di compiere questo passo mentale.

Ad esempio, ho visto più domande su Stack Overflow che essenzialmente equivalgono a "quale metodo devo implementare per far funzionare questo codice". Nota che questo non era non relativo al codice del metodo (il richiedente sapeva come implementare il metodo), era puramente relativo al nome . Tuttavia, nessuno dei richiedenti ha avuto l'idea di eseguire semplicemente il codice e guardare il nome del metodo mancante in NoMethodError eccezione che invariabilmente verrà sollevata.

97
Jörg W Mittag

TDD è un processo piacevole nella programmazione del "mondo reale" perché spesso i problemi arrivano sui nostri banchi non specificati. "Aggiungi una funzione che fa X", "correggi il bug dove mostra la cosa sbagliata se fai Y", ecc. TDD ci costringe a creare una specifica prima di iniziare la programmazione.

Nelle classi CS/di programmazione, i problemi di solito ci vengono estremamente ben specificati. "Scrivi una funzione che accetta una matrice di numeri interi e restituisce una matrice con gli stessi numeri interi disposti in ordine non decrescente". Le specifiche ci vengono consegnate.

Sono curioso di sapere perché pensi che TDD renda più facile un problematico algoritmo con una specifica ben definita. In particolare, voglio che tu spieghi questo:

Sarei quasi all'oscuro se mi chiedessero di calcolare tutte le permutazioni degli elementi in un elenco, ancora senza usare TDD. Con TDD, d'altra parte, ho risolto il problema delle permutazioni in pochi minuti quando scrivevo la risposta allo studente.

Sospetto che lo dirai perché hai scritto casi di prova che affermavano P([]) -> [[]], P([1]) -> [[1]], P([1, 2]) -> [[1, 2], [2, 1]], ecc. E che ti hanno fatto vedere come dovrebbe funzionare la ricorsione . Ma non è TDD, è solo ... pensando al problema. Puoi pensare al problema senza il processo di scrittura dei test unitari effettivi che falliscono.

53
MattPutnam

Sospetto sia principalmente perché scrivere test automatici è più difficile che scrivere il codice che si sta testando. Quando stai ancora lottando con la meccanica di base, è difficile aggiungere un altro livello. Inoltre, come hanno sottolineato altre risposte, TDD è percepito come un processo di ingegneria del software, anche se i suoi professionisti lo considerano più come un dispositivo didattico. Inoltre, sapere quali test scrivere prima è un'abilità in sé.

Se stessi insegnando un corso introduttivo, vorrei fornire alcuni test in ordine TDD, e istruire gli studenti a superare i test uno alla volta in quell'ordine. È un'esperienza molto simile associare la programmazione a un mentore esperto. Personalmente, penso che renderebbe più facili da insegnare classi come gli algoritmi, il che compenserebbe il tempo impiegato per la tecnica, a causa della progressione passo-passo. Avrebbe spinto gli studenti a pensare a domande come "Ho un codice di lavoro collaudato che troverà tutte le permutazioni di un elenco di due elementi. Come riutilizzare il maggior numero di quel codice possibile per farlo funzionare per 3+ elementi?"

33
Karl Bielefeldt

Il problema di base è che inventando i test nel processo TDD non ha nulla a che fare con l'informatica o l'ingegneria del software. Richiede la conoscenza di dominio applicazione.

Ovviamente questa è la forza di TDD nelle applicazioni del mondo reale: non puoi scappare dal pensare a quale sistema stai realizzando verrà effettivamente utilizzato. Ma nelle tipiche attività CS e SE, i compiti assegnati allo studente hanno un contesto minimo ed esistono solo per testare o illustrare alcuni obiettivi di apprendimento.

Ad esempio, se l'obiettivo di apprendimento è dimostrare la comprensione del costrutto "case" in un linguaggio di programmazione, TDD è irrilevante: è possibile scrivere software che supera tutti i test TDD senza usare affatto "case". Se l'esempio fosse artificiale, non usare "case" potrebbe in effetti essere una soluzione migliore al problema nel mondo reale, ma sebbene non in termini dell'obiettivo di apprendimento previsto.

Incoraggiare gli studenti a inventare i propri casi di test ed eseguirli, ma cercare di utilizzare un processo TDD formale non è il punto.

Un secondo problema potrebbe avere più a che fare con il modo in cui CE e SE vengono insegnate, ma è ancora pratico: come valutare lo studente raccolta di test quando si utilizza TDD? Non esiste un modo ovvio per automatizzare tale processo.

Anche se produci una soluzione modello che dice "dovresti aver testato per le seguenti 15 o 20 situazioni" devi comunque identificare manualmente quale dei test dello studente corrisponde (in tutto o in parte) a ciascuna parte della risposta del tuo modello. E, tranne in casi banali, lo studente potrebbe aver prodotto una buona serie di test che sono logicamente strutturati in modo diverso dalla risposta del modello.

9
alephzero

Lo studente medio ha davvero una brutta panoramica di ciò che dovrebbe sapere e fare. Per insegnare a TDD avrebbero bisogno di capire:

  1. Come risolvere i problemi tecnici. All'inizio pensano che il codice sia scritto in una volta sola. È solo più tardi quando realizzano strategie di debug di base che passano alla scrittura più incrementale. Anche se glielo dici in anticipo, lo faranno comunque perché pensano che sia così (anche questo è il motivo per cui le persone non sanno disegnare, suonare il piano, fare matematica, ecc. Ecc. )

  2. Come introspettare le tue azioni in modo da poter trovare modelli ripetibili nel tuo comportamento. Una volta che puoi farlo, puoi automatizzare il tuo lavoro. Ma questo è assolutamente estraneo alla maggior parte delle persone fino a quando non raggiungono un certo livello.

  3. Come scrivere i requisiti.

  4. Comprensione dei casi angolari del tuo spazio problematico.

  5. Comprensione della filosofia ingegneristica sulla gestione dei rischi. (ah ma non sai nemmeno che sei un ingegnere giusto)

  6. Comprensione del refactoring e della manutenzione del codice.

  7. Comprendere come funziona la programmazione in una vera azienda.

In effetti ho avuto colleghi che sono stati introdotti alla TDD troppo presto, non ne hanno davvero beneficiato. Tuttavia, è ancora possibile fare piccoli passi verso questo effetto. È solo che le persone hanno bisogno di un po 'di esperienza dietro di loro per trarne beneficio.

Quindi puoi insegnarlo ma non qualcosa con cui inizi. Soprattutto perché esiste un codice che non si presta molto facilmente a TDD.

8
joojaa

Il TDD non è più popolare nelle università, perché (in generale) le università svolgono un lavoro molto scarso nel garantire che le conoscenze che vengono fornite agli studenti possano essere trasferite in contesti del mondo reale.

Probabilmente, questo non è il ruolo dell'università in primo luogo, e si tratta più di insegnare i fondamenti e i concetti chiave di CS. Questo è istruttivo, importante e, essenziale, se gli studenti fossero interessati a perseguire una carriera nel mondo accademico, ma non è all'altezza quando gli studenti finiranno i loro titoli di studio e si iscriveranno al settore, lavorando integrato in una squadra, che segue lo sviluppo migliori pratiche, CI/CD, ecc.

Ovviamente, ci sono incroci ed entrambi possono beneficiare l'uno dell'altro, ma, alla fine, l'università non è ancora al passo con ciò che deve essere fatto per laurearsi ingegneri del software più capaci, pertinenti e aggiornati.

6
Bruno Oliveira

Per rispondere direttamente alla domanda:

Come qualcuno ha suggerito, c'è abbastanza apprendimento per un intero semestre. Un corso separato? Può essere. Ho potuto vedere TDD combinato con argomenti di progettazione software. Il più grande valore di IMO TDD è bloccare i comportamenti esistenti in modo da poter aggiungere nuovi comportamenti in un secondo momento e cambiare il design in modo che sia appropriato per quei nuovi comportamenti. Quindi una lezione di progettazione software?

Sarebbe bello vedere il processo di pensiero dietro TDD (mal chiamato, e una volta ho chiesto a Kent Beck se avrebbe riconsiderato, ha detto che "quel treno ha lasciato la stazione") essere introdotto il prima possibile. Ho usato il codice di imbragatura dal 1976 e so che all'inizio TDD sembrava molto innaturale. Ma ora sembra abbastanza naturale. Il mio tempo non viene recuperato scrivendo il codice di prova, viene ripristinato in seguito, quando devo solo correggere un difetto grave una volta all'anno (il software OTIS2 del Centro trapianti UofM, scritto interamente testato, ha avuto l'ultima "emergenza software" nel 2004 ).

Incoraggio i neolaureati a provarlo per un mese. Ma sarebbe molto più facile per loro se fossero stati esposti a TDD molto prima. Trovo utile usare il framework di unit test quando sto imparando una nuova lingua (Storia vera: "Ora come faccio a superare questo test in Ruby? FORSE questo funzionerà ... HEY IT WORKED!"), O esplorare una nuova libreria ("I documenti sono vaghi sull'ordine in cui verranno restituiti ... Scriverò un test ...").

Trovo TDD utile quando si implementa un algoritmo (NON ne invento uno ... Ci riuscirò), o costruendo da zero qualsiasi regola aziendale leggermente complicata. Ogni test che sta superando è "bloccato" per tutta l'eternità. Se il test è abbastanza discreto, non dovrà mai cambiare (ma quello impiega molto più di un mese per diventare bravo a).

Quindi sarebbe interessante incorporare TDD nelle classi di programmazione precedenti. Tre punti di miglioramento:

  1. Potremmo concentrarci di meno sul debug e sul break-fix, che la maggior parte degli sviluppatori ritiene essere solo la natura del loro lavoro. Non lo è. Non deve essere così doloroso o che richiede tempo.
  2. I framework di unit test sono un semplice sostituto di #ifdef DEBUG/printf ("...")/#endif - quindi abbiamo fatto qualcosa di simile (ma più rischioso) dall'inizio dei tempi.
  3. Quando sentiamo "DOVETE scrivere prima il test" veniamo fuorviati. I voglio per scrivere le mie aspettative per il codice che sto per scrivere. Voglio lasciarlo in esecuzione mentre mi concentro sul comportamento successivo o sulla pulizia del progetto.

Un'altra cosa che potrebbe essere utile è un libro di testo o, per lo meno, un curriculum senza fronzoli condensato con i laboratori progettati per trasmettere vari aspetti della pratica TDD. Ho un suggerimento per questo (vedi esperienza/disclaimer più avanti).

Per rispondere alla critica:

Sono nuovo qui, ma noto che alcune "risposte" non rispondono alla domanda, ma sono giuste critiche al TDD. Quindi immagino sia giusto affrontare alcune di queste preoccupazioni?

  1. È vero, studi condotti confrontando TDD con unit-test-after (UTA?) Mostrano che il TDD inizialmente era più lento. Tuttavia, il gruppo UTA aveva una copertura del test molto più bassa e più difetti. Penso che sia stato questo studio: Studio longitudinale sull'uso di una pratica di sviluppo basata su test nell'industria

Se gli sviluppatori che lavorano su un prodotto per più di qualche mese trascorressero davvero la maggior parte del loro tempo a scrivere nuove funzionalità, questo sarebbe negativo. Ma i sei team TDD su cui ho lavorato come sviluppatore hanno trascorso il loro tempo in questo modo, mentre il decennio che ho trascorso prima dell'imbragatura del codice prima di TDD è stato speso principalmente nel debugger, o con cautela copiando/incollando/modificando in modo da non passare più indietro/codice di qualcun altro. I vantaggi del TDD non sono tutti istantanei, ma sono stati straordinariamente affidabili e straordinariamente preziosi, misurati dai minori straordinari (e stress) dello sviluppatore e maggiori entrate = . In conclusione: non vedevo l'ora di andare a lavorare con quei team TDD. (Una volta avevo preso un po 'di tè.)

  1. È anche vero che TDD non può inventare un nuovo algoritmo. Penso che sia stato Ron Jeffries che ha cercato di creare un solutore di Sudoku usando TDD, e ha cercato di non lasciare che le sue abilità di Sudoku interferissero con l'implementazione. Ha fallito. Non sono sorpreso. TDD aiuta a scomporre, semplificare e attuare le regole aziendali; aiuta a confermare che abbiamo un algoritmo corretto (ad es. un algoritmo di crittografia complesso che potrebbe non essere riducibile); ci aiuta a rimodellare il codice in un secondo momento in modo da poter aggiungere in sicurezza nuove funzionalità; e lo fa bloccando l'investimento che abbiamo già fatto nei comportamenti del prodotto.

Quando scrivi un "test" (aka specifica, aka scenario) devi conoscere la risposta! Inoltre, si desidera scrivere un test sufficientemente piccolo dalla soluzione da avere già un'idea (conoscenza preliminare) di come implementarlo.

Ciò che spesso sorprende è quanto possa diventare chiaro e semplice il progetto se prestiamo attenzione agli odori di codice e rifattorizziamo secondo necessità ogni volta che passano tutti i test relativi a quel codice.

Nessuno ci sta suggerendo di buttare via la nostra buona conoscenza dei modelli di progettazione, o dei linguaggi linguistici, o SOLID, o come giocare a Sudoku o come scrivere un heap-sort.

TDD riguarda la creazione di una rete di sicurezza che ci dia la sicurezza di aggiungere rapidamente nuove funzionalità e modificare il design per adattarle a quelle nuove funzionalità senza interrompere nient'altro.

UTA sta riparando la rete di sicurezza dopo che qualcuno è caduto in un buco fino alla morte. (Nota a margine interessante: il progetto OTIS2 è un sistema critico per la vita, quindi il rischio di morte dei pazienti non è stato uno scherzo per noi. Oltre 20.000 test tutti in esecuzione in 10 minuti, ora that è un safetynet!)

Esperienza/Avvertenze:

Ho fatto TDD praticamente a tempo pieno dal 1998 al 2004 e con ~ 6 squadre diverse. Tutti sono stati almeno 6 mesi di sviluppo. Prima di allora, avevo trascorso 13 anni a scrivere software nell'altro modo, e sono arrivato a odiare i debugger e i test manuali con printf ().

Ho iniziato a insegnare pratiche di sviluppo software nel 2001, ora includendo corsi TDD, BDD e SA-CSD. Certo, è una bella vita, ma so anche che TDD è un modo semplice per rendere lo sviluppo del software incentrato sul team sano e divertente di nuovo. Così...

Sto scrivendo quello che spero diventerà un libro di testo per un college o una scuola superiore (con repository online, laboratori, video, ecc. Ovviamente): Essential Test-Driven Development

4
user30938

Non ho mai considerato utile TDD come un modo per risolvere effettivamente un problema e dopo aver letto la tua domanda ancora non lo faccio.

TDD ti costringe semplicemente a guardare un problema da un lato: il fine del cliente. Questo può aiutarti a evitare di trovare una soluzione che non corrisponda alla domanda del cliente. Questa è generalmente una buona cosa, anche se potrebbe anche limitarti, ti impedisce di guardare il problema da una prospettiva più ampia, potrebbe esserci una soluzione migliore e più generale al problema che il tuo cliente non ha preso in considerazione.

Un altro modo di vederlo è che è l'approccio top down top. TDD potrebbe essere l'acronimo di Top Down Development. Inizi lo sviluppo al livello più alto del corso e ingrandisci gradualmente.

Ad ogni modo, è un concetto astratto. Puoi parlarne a uno studente, fornire una definizione, ma sarà così. Non puoi porre così tante domande al riguardo in un esame. Quindi in qualsiasi classe SE o CS, sebbene utile in un contesto SE, non potrebbe mai essere più che una nota a margine.

4
Martin Maat

Mi è stato insegnato scienze informatiche negli anni '70, molto prima che fosse inventato l'acronimo TDD, e ovviamente non ci era mai stata insegnata esplicitamente la tecnica. Ma per uno degli esercizi di programmazione che ci hanno dato, ci è stato fornito un set di casi di test e ci è stato detto che la nostra soluzione doveva superare i test. Così ho imparato il valore dell'approccio senza mai averlo insegnato esplicitamente e da allora l'ho usato.

4
Michael Kay

Mentre scrivere test è un'abilità essenziale per lo sviluppo del software, l'evidenza scientifica non indica che TDD finisca per produrre software migliore dello sviluppo iterativo test-last (ITL) (OTOH, ma non lo è peggiore ).

Per prove, puoi vedere Davide Fucci et al. "Una replica esterna sugli effetti dello sviluppo guidato dai test usando un approccio di analisi cieca multi-sito" ( link ) e la meta-analisi di Turhan et al nel Making Software ( link ).

Quindi, a meno che non iniziamo a vedere prove contrarie del fatto che il TDD fornisce effettivamente guadagni misurabili, è meno importante che il TDD come pratica specifica venga insegnato piuttosto che semplicemente instillare la buona abitudine di scrivere test ad un certo punto del processo di sviluppo.

3
Anzel

ma passerei comunque un po 'di tempo a scrivere un algoritmo di ordinamento di elenchi senza TDD, se richiesto, e sarei quasi all'oscuro se mi chiedessero di calcolare tutte le permutazioni degli elementi in un elenco, ancora senza usare TDD. Con TDD, d'altra parte, ho risolto il problema delle permutazioni in pochi minuti

Questo mi sta confondendo sul serio.
Per me lo sviluppo guidato dai test significa pensare ai test in anticipo e impiegare il tempo per implementarli e tenerli aggiornati con il codice.
Naturalmente pensare a cosa testare è una buona occasione per elaborare il problema da risolvere e in alcuni casi avere una buona immagine di quali sono le insidie.
Ma non fare TDD, non concentrarsi prima sui test non proibisce comunque di pensare al problema di fondo. Dovresti sempre pensare a ciò che fai e chiarire la situazione, non importa se vuoi fare un altro passo e implementare i test adesso o no.

sarebbe problematico spiegare l'approccio TDD prima di chiedere agli studenti di scrivere algoritmi di ordinamento delle liste e cose simili?

Dipende da quanto spiegheresti TDD.
È utile sapere qualcosa. Ma gli studenti ascoltano molte cose che non possono ancora interpretare perché mancano ancora altre basi. Quindi non dovresti andare troppo in profondità nel concetto che senza la conoscenza delle basi sarebbe un casino inutile e alienante di termini sconosciuti per loro.
Oltre a ciò, probabilmente molti programmatori sanno cosa si prova se stai cercando un how-to su qualche problema e trovano esempi che effettivamente mostrano una soluzione, ma prima di tutto devi risolvere tutti i tipi di altre cose irrilevanti l'autore ha aggiunto.

Quindi, per rispondere a questa domanda, se fossi uno studente mi piacerebbe che le cose fossero separate. Se annunci di spiegarci come ordinare un elenco, ti preghiamo di dirci come farlo, ma non lasciare il percorso per compilare i test. Se vuoi iniziare a spiegare i test, allora non annunciare di implementare l'ordinamento perché ciò non accade ancora per molto tempo.
Ancora una volta è necessario pensare prima di iniziare a scrivere l'ordinamento o i test. Che aspetto hanno gli elenchi prima e dopo l'ordinamento? Fai esempi, pensa alle insidie, cosa deve essere considerato per evitare di fallire quando un elenco è vuoto e così via. Tutto questo deve essere considerato, ma non è stata ancora scritta una linea di test.

Generalmente direi che stai mescolando due cose che dovrebbero essere tenute separatamente.

  • Pensando alla natura del problema che vuoi risolvere.
  • Pensando all'input per il tuo codice e quale output dovrebbe essere dato.

Pensare al problema è molto diverso dal concentrarsi sulla scrittura di casi di test.

Come farlo male

Una volta mi sono imbattuto in un esempio di TDD da qualcuno che era un po 'ossessionato dal TDD.
.

L'autore solo concentrato sui casi di test, non sul problema che il loro codice dovrebbe gestire. Poiché non è mai possibile trovare tutte le permutazioni di input, è necessario disporre di una panoramica di ciò che si sta effettivamente facendo, è necessario visualizzare l'intero problema. Non è sempre possibile iniziare con input vuoti, quindi successivamente aggiungere altri input e aggiungere sempre il codice per gestire correttamente i nuovi input.
Devi avere un'idea di cosa hai effettivamente a che fare in generale. Ma l'autore no.

Se provo a tradurlo nell'ordinamento di un elenco, inizieremmo con un elenco vuoto, quindi un elemento che può essere restituito così com'è, un elenco con due elementi che forse devono essere scambiati e forse finire in una ricorsione perché tre elementi sono come due (l'abbiamo già risolto) più un altro con un passo in più ...
Un orribile szenario per un algoritmo di ordinamento, ma nessuno se ne renderà conto perché ci concentriamo solo su casi di test.

Conclusione

I commenti mi fanno scrivere qualcosa in più sulla mia opinione.

Penso che il termine "sviluppo guidato dai test" sia sbagliato. Dovrebbe essere "sviluppo supportato da test", nel senso che non ci limitiamo a programmare e sperare, ma pensiamo anche ai test e sappiamo che è sempre bene sapere in anticipo quando qualcosa va storto.

Se lo sviluppo viene chiamato guidato dai test, questo potrebbe implicare che tutto dipende solo dai test e lo facciamo non appena vengono soddisfatti un paio di casi di test. Questa richiesta sarebbe soddisfatta anche da un codice molto insufficiente che non ha mai provato a vedere un problema nel suo insieme ma è stato violato avanti e indietro fino a quando tutti i casi di test diventano acutamente verdi, quindi falliscono nel funzionamento reale.

2
puck

Hai aggiornato la tua domanda per essere più "Perché il TDD non viene insegnato come strumento di apprendimento di base?". Altre risposte spiegano già abbastanza bene perché TDD non è un buon argomento per la codifica 101, ma la risposta principale è proprio che TDD, in sostanza, non è uno strumento di risoluzione dei problemi. Può essere utilizzato a tale scopo, ma come qualsiasi strumento devi prima capire quando e come usarlo.

TDD è un processo di test e quindi, naturalmente, verrà insegnato come parte di un corso sui Processi di sviluppo o come parte di un corso di Test del software. Nella codifica dei corsi 101, l'obiettivo non è che gli studenti risolvano i problemi, è insegnare loro come utilizzare vari concetti di programmazione. Generalmente, la maggior parte dei progetti di codifica 101 e 102 sarà molto esplicita su come risolvere il problema, gli studenti devono solo capire cosa hanno imparato a svolgere l'attività in un modo non copia-incolla.

Ogni studente impara in modi diversi. Alcuni studenti hanno bisogno di leggerlo, altri ne hanno una spiegazione verbale e altri non lo capiranno mai a meno che non abbiano una conoscenza approfondita del codice. Insegnare TDD per aiutare nel processo di apprendimento non aiuterà effettivamente la maggior parte degli studenti, e quelli che aiuta? Gli insegnanti dovranno decidere se il tempo necessario per insegnare TDD è valso la maggiore velocità di apprendimento. Nel complesso, insegnare qualsiasi metodo di apprendimento non varrà il tempo della lezione che potrebbe essere speso su argomenti specifici del corso. (In generale, le abilità di apprendimento e di risoluzione dei problemi sono generalmente lasciate agli studenti per apprendere se stessi, poiché solo lo studente può identificare ciò che funziona meglio per loro)

TL: RD; Diverse persone hanno diversi processi efficaci. Le università non prescrivono come dovresti fare qualsiasi cosa; Ti do solo gli strumenti in modo da poter fare ciò che funziona meglio per te.

1
Tezra

TDD è un fantastico strumento di implementazione e penso che tu abbia ragione sul fatto che sia benefico per coloro che desiderano scrivere software.

Qual è il motivo per cui il TDD non viene insegnato affatto o almeno molto tardi nelle università? In altre parole, sarebbe problematico spiegare l'approccio TDD prima di chiedere agli studenti di scrivere algoritmi di ordinamento delle liste e cose simili?

Probabilmente il motivo principale è che i professori che insegnano questi programmi raramente sanno come sviluppare software, poiché questo non è il loro campo di competenza. Come altre risposte hanno già detto, l'informatica e l'ingegneria del software sono discipline diverse e vorrei confrontare le aspettative che gli studenti di informatica imparano l'ingegneria del software con gli studenti di fisica che imparano come progettare automobili. TDD è un'abilità che richiede una discreta quantità di pratica per essere davvero in grado di insegnare in modo efficace, e i professori di informatica passano gran parte della loro carriera lavorando sull'informatica, quindi si aspettano che la facoltà di informatica sia davvero in grado di insegnare il TDD in un modo ciò non confonderà semplicemente i loro studenti, secondo me è piuttosto irrealistico.

Dobbiamo considerare l'informatica e lo sviluppo di software professionale come i campi distintamente separati che sono. Se il tuo obiettivo è imparare l'informatica, non dovresti essere gravato dal pagare migliaia di dollari imparando a creare siti Web in React in modo errato da qualcuno che ha trascorso gli ultimi 30 anni della sua carriera facendo grafico teoria su una lavagna. Allo stesso modo, se il tuo obiettivo è diventare un ingegnere del software, non so perché vorresti spendere 4 anni e decine di migliaia di dollari per imparare ciò che è essenzialmente solo un campo specifico della matematica. per avere una comprensione di base nel campo, proprio come chi progetta un collettore di scarico deve comprendere una certa quantità di fisica, tuttavia la persona che progetta il collettore di scarico non ha bisogno di una comprensione troppo approfondita nella meccanica quantistica, nella relatività speciale, e elettromagnetismo per fare il loro lavoro.

Se vuoi diventare un contabile, puoi ottenere una laurea in contabilità e probabilmente i tuoi professori saranno stati tutti CPA in un punto o nell'altro. Se vuoi essere un ingegnere meccanico, puoi ottenere una laurea in ingegneria meccanica e probabilmente i tuoi professori saranno stati tutti ingegneri autorizzati in un punto o nell'altro. Ma se vuoi essere un ingegnere del software, qualsiasi laurea in ingegneria del software sarà in realtà solo una laurea in informatica con alcuni dei tuoi elettivi già scelti per te, e quasi nessuno dei tuoi professori sarà mai stato uno sviluppatore di software professionale. La laurea in contabilità non fa parte del dipartimento di matematica e la laurea in ingegneria meccanica non fa parte del dipartimento di fisica, ma la laurea in ingegneria del software farà quasi sempre parte del dipartimento di informatica. Fino a quando il mondo accademico nel suo complesso non separa completamente questi due campi in dipartimenti diversi gestiti da personale diverso, penso che ci sarà sempre un lungo elenco di cose come TDD che non vengono insegnate agli studenti che aspirano ad essere ingegneri del software.

1
Dogs