L'aggiunta di test unitari ha senso per codice legacy noto?

21
  • Sto parlando di test unitari nel senso TDD. ("Integrazione" non automatizzata, o quello che ti piace chiamarlo test.)
  • Codice legacy come in: codice (C ++) senza test. (vedi: Michael Feathers ' Funzionante in modo efficace con il codice legacy )
  • Ma anche codice legacy come in: Codice con cui il nostro team ha lavorato per gli ultimi 10-5 anni, quindi molto spesso abbiamo una buona idea di dove mettere le cose per cambiare qualcosa.
  • Facciamo test di unità in atto (tramite Boost.Test) per alcuni moduli che sono venuti dopo o sono stati adattati "naturali" ai test di unità (contenitori specifici per app comuni, string-stuff, helper di rete, ecc.)
  • Non abbiamo ancora test di accettazione automatici adeguati.

Ora, di recente ho avuto il "piacere" di implementare 3 nuove funzionalità per gli utenti.

Ognuno di quelli mi ha impiegato circa 1-2 ore per arrivare al massimo con le parti del codice che dovevo cambiare, 1-2 ore per implementare il (piccolo) codice che dovevo cambiare e altre 1-2 ore per fare certo che l'app ha funzionato correttamente in seguito e ha fatto è stato dovrebbe farlo.

Ora, ho davvero aggiunto un piccolo codice. (Penso che un metodo e alcune linee di chiamata per ogni funzione.)

Factoring out this code (tramite uno qualsiasi dei metodi suggeriti in WEwLC ), in modo che un test unitario avesse senso (e non fosse una completa tautologia) avrebbe facilmente preso altre 2-4 ore, se non di più. Questo avrebbe aggiunto il 50% -100% del tempo a ciascuna funzione, senza alcun beneficio immediato, come

  1. Non avevo bisogno del test dell'unità per capire qualcosa sul codice
  2. Il test manuale ha la stessa quantità di lavoro, poiché ho ancora bisogno di testare se il codice è correttamente integrato nel resto dell'app.

Certo, se , più tardi, "qualcuno" è arrivato e ha toccato quel codice, lui teoricamente potrebbe trarre qualche beneficio da quel test unitario. (Solo in teoria, poiché quell'isola di codice collaudata vivrebbe in un oceano di codice non testato.)

Quindi, "questa volta" ho scelto di non fare il duro lavoro di aggiungere un test unitario: Il codice cambia per ottenere quella roba da testare sarebbe stato molto più complesso delle modifiche al codice per ottenere correttamente la funzione (e pulito) implementato.

Questo è tipico del codice legacy strongmente accoppiato? Sono pigro / impostiamo le priorità sbagliate come una squadra? O sono prudente, sto solo testando cose in cui il sovraccarico non è troppo alto?

    
posta Martin Ba 24.10.2011 - 11:06
fonte

6 risposte

18

Devi essere pragmatico riguardo a queste situazioni. Tutto deve avere un valore aziendale, ma l'azienda deve fidarsi di te per giudicare qual è il valore del lavoro tecnico. Sì, c'è sempre un vantaggio nell'avere dei test unitari, ma è un beneficio abbastanza grande da giustificare il tempo trascorso?

Vorrei discutere sempre sul nuovo codice ma, su un codice legacy, devi fare un giudizio.

Sei spesso in quest'area di codice? Poi c'è un caso per il miglioramento continuo. Stai facendo un cambiamento significativo? Poi c'è un caso che è già un nuovo codice. Ma se stai realizzando un codice a una riga in un'area complessa che probabilmente non verrà più toccata per un anno, ovviamente il costo (per non parlare del rischio) di reingegnerizzazione è troppo grande. Basta schiaffeggiare la tua riga di codice e andare a fare una doccia veloce.

Regola empirica: pensa sempre a te stesso, " Credo che gli affari traggano beneficio più da questo lavoro tecnico che sento che dovrei fare piuttosto che dal lavoro che hanno chiesto e che di conseguenza sarà ritardato? "

    
risposta data 24.10.2011 - 11:47
fonte
10

Il guadagno dei test unitari in senso TDD è quello di ottenere qualcosa che si regge da solo, senza bisogno di una tradizione orale costruita negli anni da una squadra stabile.

È una grande fortuna che lo stesso team sia stato sullo stesso progetto per così tanto tempo. Ma questo alla fine cambierà. Le persone si ammalano, si annoiano o promuovono. Si muovono, si ritirano o muoiono. I nuovi arrivano con nuove idee e l'impulso di rifattorizzare tutto nel modo in cui hanno imparato a scuola. Le aziende vengono vendute e acquistate. Le politiche di gestione cambiano.

Se vuoi che il tuo progetto sopravviva, devi prepararlo per le modifiche.

    
risposta data 24.10.2011 - 11:22
fonte
3

Scrittura di unit test è la prova del codice futuro. Se il code base non ha test, allora dovresti aggiungere nuovi test per tutte le nuove funzionalità perché rende quel bit del codice solo un po 'di più robusto.

Trovo che l'aggiunta di test, anche nel codice precedente, sia utile nel medio-lungo periodo. Se alla tua azienda non interessa il medio-lungo termine, cercherò un'altra azienda. Inoltre, non penso che ci voglia più tempo per testare manualmente di quanto ci vuole per scrivere un test unitario. Se lo fa, allora hai bisogno di praticare il codice Kata focalizzato sulla scrittura dei test.

    
risposta data 24.10.2011 - 11:22
fonte
2

Certamente le migliori pratiche impongono di testare l'unità con qualsiasi codice che modifichi. La codifica del mondo reale comporta tuttavia molti compromessi, tempo e materiali sono limitati.

Quello che devi fare è valutare il costo in termini reali di correggere bug e apportare modifiche senza test unitari. È quindi possibile valutare contro l'investimento nella creazione di tali test. I test unitari riducono notevolmente il costo del lavoro futuro, ma ora hanno un prezzo.

La linea di fondo è che se il tuo sistema viene cambiato raramente allora potrebbe non valere la pena di scrivere test unitari, ma se è soggetto a cambiamenti regolari, ne varrà la pena.

    
risposta data 24.10.2011 - 11:30
fonte
1

Tutte queste piccole decisioni razionali per non creare test stanno creando un debito tecnico paralizzante che tornerà a perseguitarti quando qualcuno lascerà & una nuova assunzione deve venire in & mettiti al passo.

Sì, potrebbero essere necessarie altre 2-3 ore per scrivere i test unitari, ma se il codice viene restituito dai test, dovrai testare di nuovo tutto di nuovo e documentare i test, ancora una volta - fai quel don ' tu? Altrimenti come fa qualcuno a sapere cosa hai testato e quali valori hai usato?

I test unitari documentano il comportamento previsto del codice, i dati del test utilizzati per verificare la funzionalità e danno ai nuovi programmatori la ragionevole certezza che non abbiano rotto qualcosa durante le modifiche.

Oggi costa più di un paio di ore rispetto ai test manuali, ma poi esegui dei test ogni volta che modifichi le ore di salvataggio per tutta la durata del codice.

Tuttavia, se sai che il codice verrà ritirato in un paio di anni, non ho detto tutte le modifiche perché non terminerai di mettere i test nel codice & non ripagherà mai.

    
risposta data 24.10.2011 - 11:56
fonte
0

Il valore dei test unitari non si limita a testare una nuova funzione quando viene sviluppata. Il vantaggio dei test unitari si ottiene principalmente in futuro.

Sì, potresti dover spendere ciò che sembra come una quantità eccessiva di tempo per rendere testabile il tuo codice legacy.

Ma se non lo fai, lo farai, o certamente dovrebbe , spendere molte, molte, molte più ore a testare la funzionalità. Non solo nel suo sviluppo iniziale, ma con ogni nuova versione del tuo software. Senza test unitari tu e altre forme di test automatizzati, non hai altra scelta che passare molte ore di test manuali per assicurarti che la tua funzione non sia stata inavvertitamente interrotta, anche quando quella funzionalità non è stata modificata.

    
risposta data 24.10.2011 - 12:25
fonte

Leggi altre domande sui tag