Quando è appropriato non test unitario?


139

Lavoro in una piccola azienda come sviluppatore solista. In realtà sono l'unico sviluppatore dell'azienda. Ho diversi progetti (relativamente) di grandi dimensioni che ho scritto e gestito regolarmente, e nessuno di essi ha test a supporto. Quando inizio nuovi progetti mi chiedo spesso se dovrei provare un approccio TDD. Sembra una buona idea, ma onestamente non posso mai giustificare il lavoro extra in questione.

Lavoro duro per essere lungimirante nel mio design. Mi rendo conto che sicuramente un giorno un altro sviluppatore dovrà mantenere il mio codice o almeno risolverlo. Tengo le cose il più semplice possibile e commentare e documentare cose che sarebbero difficili da comprendere. E il fatto è che questi progetti non sono così grandi o complicati che uno sviluppatore decente farebbe fatica a comprenderli.

Molti degli esempi che ho visto di test passano alle minuzie, coprendo tutti gli aspetti del codice. Dato che sono l'unico sviluppatore e sono molto vicino al codice nell'intero progetto, è molto più efficiente seguire un modello di test di scrittura e di test manuale. Trovo anche che i requisiti e le funzionalità cambino abbastanza frequentemente che il mantenimento dei test aggiungerebbe una notevole quantità di resistenza su un progetto. Tempo che altrimenti potrebbe essere speso per risolvere le esigenze aziendali.

Quindi finisco sempre con la stessa conclusione. L'utile sul capitale investito è troppo basso.

Occasionalmente ho impostato alcuni test per assicurarmi di aver scritto correttamente un algoritmo, come il calcolo del numero di anni in cui qualcuno è stato in azienda in base alla data di assunzione. Ma dal punto di vista della copertura del codice ho coperto circa l'1% del mio codice.

Nella mia situazione, troveresti ancora un modo per rendere le prove unitarie una pratica regolare o sono giustificato per evitare questo sovraccarico?

AGGIORNAMENTO: Alcune cose sulla mia situazione che ho lasciato fuori: I miei progetti sono tutte applicazioni web. Per coprire tutto il mio codice, dovrei usare i test UI automatizzati, e questa è un'area in cui ancora non vedo un grande vantaggio rispetto ai test manuali.


1
Grazie a tutti. Sto imparando molto qui. Alcune cose sulla mia situazione che ho lasciato fuori: i miei progetti sono tutte applicazioni web. Per coprire tutto il mio codice, dovrei usare i test UI automatizzati, e questa è un'area in cui ancora non vedo un grande vantaggio rispetto ai test manuali.
Ken Pespisa,

1
Stiamo ottenendo un grande successo in Transactis utilizzando lo strumento di test dell'automazione web di Telerik. Abbiamo già dozzine di test del browser precedentemente manuali convertiti in automazione. I test automatizzati sono VELOCEMENTE più veloci e sono anche GRANDI per evidenziare eventuali problemi di prestazioni del tuo sito web.
John Kaster,

2
Ho visto un progetto che ha cercato di testare automaticamente il browser di pagine Web complete. Per quanto ne so, non ha trovato nessuno dei centinaia di gravi bug che abbiamo riscontrato attraverso i test manuali e ha richiesto un enorme dispendio di tempo per lo sviluppo e la manutenzione. (Usando il selenio guidato da NUnit). Peggio ancora, alcuni dei test si interrompono frequentemente per non problemi, a causa di incompatibilità del browser e del framework di test.
O'Rooney,

1
Questa non è davvero una risposta, solo un'osservazione ... la tua argomentazione contro l'unità-test perché "i requisiti cambiano troppo frequentemente" mi ricorda l'argomento inverso che sento dove lavoro: "i nostri programmi sono così statici, qual è il punto di test vero? Non cambia quasi mai! " ;)
Bane,

2
I test automatizzati dell'interfaccia utente dell'applicazione web non sono test unitari, sono una bestia completamente diversa e non ti biasimerei se non li volessi fare. Ma tutto il codice aziendale dovrebbe essere nel backend, ed è quello che dovresti testare.
Nyamiou The Galeanthrope

Risposte:


85

Molti degli esempi che ho visto di test passano alle minuzie, coprendo tutti gli aspetti del codice.

Così? Non devi testare tutto . Solo le cose rilevanti.

Dato che sono l'unico sviluppatore e sono molto vicino al codice nell'intero progetto, è molto più efficiente seguire un modello di test di scrittura e di test manuale.

Questo è in realtà falso. Non è più efficiente. È davvero solo un'abitudine.

Quello che fanno gli altri sviluppatori solisti è scrivere uno schizzo o una struttura, scrivere i casi di test e quindi riempire la struttura con il codice finale.

È molto, molto efficiente.

Trovo anche che i requisiti e le funzionalità cambino abbastanza frequentemente che il mantenimento dei test aggiungerebbe una notevole quantità di resistenza su un progetto.

Anche questo è falso. I test non sono la resistenza. Le modifiche ai requisiti sono il trascinamento.

Devi correggere i test per riflettere i requisiti. Che si tratti di minuzie o di alto livello; scritto per primo o per ultimo.

Il codice non viene eseguito fino al completamento dei test. Questa è l'unica verità universale del software.

Puoi avere un test di accettazione "eccolo" limitato.

Oppure puoi fare alcuni test unitari.

Oppure puoi avere entrambi.

Ma qualunque cosa tu faccia, c'è sempre un test per dimostrare che il software funziona.

Suggerirei che un po 'di formalità e una piacevole suite di strumenti di unit test rendono questo test molto più utile.


8
Mi piace la tua prima affermazione, per testare solo le cose rilevanti. Per quanto riguarda l'efficienza del test manuale o unitario, non credo che la mia affermazione sia del tutto falsa, né la tua sia del tutto vera. Sembra che ci sia un equilibrio tra test automatici e manuali per raggiungere la massima efficienza.
Ken Pespisa,

9
@Ken Pespisa: Siamo spiacenti. Ho bevuto il TDD Kool-Aid circa due anni fa (dopo 30 anni di test-last). Ora sono bloccato sul test prima. Mi ha reso molto, molto più produttivo perché ho meno pensieri da fare durante la costruzione.
S.Lott

3
@Ken Pespisa: No. C'è un equilibrio nelle risposte. Se ti chiedessi se è giusto dividere per zero, otterresti risposte schiaccianti appoggiandosi in un modo per un motivo. Se ti chiedessi se sqrt(-1)dovrebbe essere un numero intero, otterrai risposte travolgenti inclinate in un modo. Il saldo è intorno a "come" e "quale ordine". Il fatto è che devi testarlo. Quindi scrivi prima i test e assicurati che funzionino.
S.Lott

21
Considerare l'unità di test dell'interfaccia non i dettagli di implementazione. Prova i limiti e i casi limite. Prova il codice rischioso. Un sacco di codice è abbastanza semplice da verificare mediante ispezione, sebbene l'ispezione del codice sia più soggetta a errori rispetto all'ispezione del codice di qualcun altro. I test manuali per la prima volta potrebbero essere più efficienti, mentre per la decima volta i test automatizzati sono molto avanti.
BillThor

10
"Il codice non viene fatto fino a quando i test non passano" - Non proprio, IMO. Il codice inizia quando supera i test. Il codice non viene eseguito fino a quando non è attivo da un anno o due ed è stato sottoposto a stress test e test di integrazione con una base di utenti ampia, attiva e impaziente. Questo è l'unico test che conta davvero.
Vector

108

Immagina di avere una serie di test che potrebbero essere eseguiti in un batter d'occhio e che accenderebbero una luce verde o rossa. Immagina che questa serie di test abbia testato tutto ! Immagina che tutto ciò che dovevi fare per eseguire la suite di test era digitare ^ T. Quale potere ti darebbe?

Potresti apportare una modifica al codice senza paura di rompere qualcosa? Potresti aggiungere una nuova funzionalità senza il timore di romperne una vecchia? Potresti ripulire rapidamente il codice disordinato senza paura di fare danni?

Sì, potresti fare tutte quelle cose! E cosa succederebbe nel tempo al tuo codice? Diventerebbe sempre più pulito perché non ci sarebbe alcun rischio per pulirlo.

Immaginiamo di avere una piccola fata sulla spalla. Ogni volta che scrivevi una riga di codice, la fata aggiungeva qualcosa alla suite di test che verificava che quella riga di codice facesse quello che doveva fare. Quindi ogni paio di secondi potresti premere ^ T e vedere che l'ultima riga di codice che hai scritto ha funzionato.

Quanto debug pensi di fare?

Se questo sembra fantasia, hai ragione. Ma la realtà non è molto diversa. Sostituisci il battito di ciglia con pochi secondi e la fata con la disciplina TDD, e praticamente ce l'hai.

Diciamo che stai tornando a un sistema che hai costruito un anno fa e hai dimenticato come creare uno degli oggetti centrali. Esistono test che creano quell'oggetto in ogni modo in cui può essere creato. Puoi leggere quei test e correre la tua memoria. Devi chiamare un'API? Esistono test che chiamano quell'API in ogni modo in cui può essere chiamata. Questi test sono piccoli documenti , scritti in una lingua che capisci. Sono completamente inequivocabili. Sono così formali da eseguire. E non possono uscire dalla sincronizzazione con l'applicazione!

Non vale l'investimento? Mi stai prendendo in giro! Come si può NON volere quella suite di test? Fatti un favore e smetti di cavillare sulla stupidità. Impara a fare bene TDD e guarda quanto sei più veloce e quanto più pulito è il tuo codice.


29
Wow, LO Zio Bob? È fantastico avere qui i tuoi pensieri. Concordo con te sui vantaggi di TDD, non c'è davvero alcun argomento da discutere. La domanda riguarda l'investimento di tempo e il ROI. Non è sciocco per me considerare queste cose. Immagina che un progetto mi impiegherà il 50% in più di tempo per terminare con TDD che senza, e la fata mi dice che mi farà risparmiare solo il 10% di tempo rispetto ai test manuali nella vita del progetto. Potrebbe sembrare una fantasia, ma lo vedo come del tutto plausibile con alcuni progetti.
Ken Pespisa,

11
@Ken "Immagina che un progetto impiegherà il 50% in più di tempo per terminare con TDD che senza". Mi sembra ESATTAMENTE una fantasia. In effetti, sembra che tu l'abbia appena inventato sul posto senza una briciola di prove a supporto.
Rein Henrichs,

18
@Rein Henrichs - Certo che ho inventato il numero, era un'affermazione ipotetica. Sto sottolineando che TDD aggiunge una notevole quantità di tempo a un progetto e devo considerare se otterrò in cambio qualcosa di valore uguale o migliore. Non devi convincermi sui valori di TDD, ne sono convinto. Ma non è una panacea.
Ken Pespisa,

11
@Rein, che cosa sono esattamente le "prove disponibili?" Per favore, elabora.
Ken Pespisa,

22
@Uncle Bob "Sostituisci l'occhiolino con pochi secondi": Stai scherzando, ovviamente. TDD è un buon strumento, ma devi testare solo le parti pertinenti, altrimenti trascorri più tempo a mantenere i test che a fare qualsiasi sviluppo serio. Ciò è particolarmente vero quando i requisiti cambiano molto rapidamente: scrivi e butti costantemente test per le classi che cambiano continuamente. Non sto dicendo che TDD sia un male, deve solo essere usato in modo sensato e non applicato meccanicamente come sembra suggerire.
Giorgio,

34

L'errore che stai commettendo è che stai vedendo i test come un investimento nel tempo senza un ritorno immediato. Non funziona necessariamente così.

In primo luogo la scrittura di test ti focalizza davvero su ciò che questa parte del tuo codice deve fare.

In secondo luogo, eseguirli rivela bug che altrimenti verrebbero fuori nei test.

In terzo luogo, eseguirli a volte mostra bug che altrimenti non emergerebbero nei test e quindi ti morderebbero davvero nel culo in produzione.

In quarto luogo, se si verifica un bug con un sistema in esecuzione e si crea un test unitario, non sarà possibile reintrodurre il bug in un secondo momento. Questo può essere di grande aiuto. I bug reintrodotti sono comuni e molto fastidiosi.

In quinto luogo, se mai dovessi consegnare il codice a qualcun altro, una suite di test renderà la sua vita molto più semplice. Inoltre, se hai ignorato un progetto e torni ad esso dopo alcuni anni, non sarai più così vicino ad esso e ti sarà utile anche.

La mia esperienza è stata costantemente che attraverso lo sviluppo di un progetto, avere test unitari decenti ha sempre reso il processo più rapido e affidabile.


2
@Ken, le suite di test sono specifiche in una forma eseguibile.

32

I ragazzi di JUnit (Java Unit test framework) hanno una filosofia secondo cui se è troppo semplice testarlo, non testarlo . Consiglio vivamente di leggere le domande frequenti sulle migliori pratiche , in quanto è abbastanza pragmatico.

TDD è un diverso processo di scrittura del software. La premessa di base alla base del test unitario è che trascorrerai meno tempo nel debugger a esaminare il codice e a capire più rapidamente se la modifica del codice rompe accidentalmente qualcos'altro nel sistema. Questo si adatta a TDD. Il ciclo TDD è così:

  1. Scrivi un test
  2. Guardalo fallire (dimostra di avere qualcosa da fare)
  3. Scrivi solo ciò che è necessario per superare il test, non di più.
  4. Guardalo passare (yay!)
  5. Refactor (rendilo migliore)
  6. Lavare, risciacquare e ripetere

Ciò che è meno ovvio sull'applicazione di TDD è che cambia il modo in cui il tuo codice di scrittura . Forzandoti a pensare a come testare / validare il funzionamento del codice, stai scrivendo un codice verificabile. E dal momento che stiamo parlando di unit test, questo di solito significa che il tuo codice diventa più modulare. Per me, il codice modulare e testabile è un grande vantaggio.

Ora, devi testare cose come le proprietà C #? Immagina una proprietà definita come questa:

bool IsWorthTesting {get; set;}

La risposta sarebbe "no" non vale la pena testarla, perché a questo punto stai testando la funzionalità della lingua. Fidati che i ragazzi della piattaforma C # hanno capito bene. Inoltre, se non è riuscito, cosa potrebbe fare per risolvere il problema?

Inoltre, scoprirai che ci sono alcune parti del tuo codice che molto bene saranno troppi sforzi per testarle correttamente. Ciò significa che non farlo, ma assicurati di testare il codice che utilizza / viene utilizzato dal problema complicato:

  • Eccezioni verificate che possono verificarsi solo se un'installazione è andata male. Java ha un sacco di questi. È necessario scrivere un blocco catch o dichiarare l'eccezione selezionata anche se non è possibile che non riesca senza eseguire l'hacking dei file installati.
  • Interfacce utente. Trovare il controllo sotto test e invocare gli eventi giusti per simulare le azioni di un utente sono molto problematici e in alcuni casi impossibili. Tuttavia, se si utilizza il modello / vista / modello controller, è possibile assicurarsi che il modello e i controller siano testati e lasciare la parte della vista al test manuale.
  • Interazioni client / server. Questo non è più un test unitario e ora è un test di integrazione . Scrivi tutte le parti che arrivano all'invio e alla ricezione di messaggi via cavo, ma in realtà non vanno oltre il cavo. Un buon approccio è quello di ridurre la responsabilità del codice che in realtà comunica attraverso il filo alle comunicazioni non elaborate. Nel codice dell'unità test, simulare l'oggetto di comunicazione per assicurarsi che i servizi si comportino come previsto.

Che ci crediate o no, TDD ti aiuterà a cadere in un ritmo di sviluppo sostenibile. Non è per magia, ma piuttosto perché hai un circuito di feedback stretto e sei in grado di cogliere rapidamente errori davvero stupidi. Il costo per correggere quegli errori è essenzialmente costante (almeno per scopi di pianificazione) perché i piccoli errori non crescono mai per diventare grandi errori. Confrontalo con la natura bursty degli sprint di eliminazione del codice binge / debug.


24

Devi bilanciare il costo del test con il costo dei bug.

Scrivere un test unitario a 10 righe per una funzione che apre un file, in cui l'errore è "file non trovato" non ha senso.

Una funzione che fa qualcosa di complesso con una struttura di dati complessa, quindi ovviamente sì.

La parte difficile è nel mezzo. Ma ricorda che il vero valore dei unit test non sta testando la particolare funzione, sta testando le interazioni difficili tra di loro. Quindi un test unitario che rileva che una modifica di un bit di codice, interrompe una funzione in un modulo diverso a 1000 righe di distanza, vale il suo peso nel caffè.


23

Il test è il gioco d'azzardo.

La creazione di un test è una scommessa che il costo dei bug in un'unità che si verificano e che non li cattura con quel test (ora e durante tutte le future revisioni del codice) è maggiore del costo di sviluppo del test. Tali costi di sviluppo dei test includono cose come il libro paga per la progettazione aggiuntiva dei test, il time-to-market aggiunto, i costi di opportunità persi dal non codificare altre cose, ecc

Come ogni scommessa, a volte vinci, a volte perdi.

A volte il software in ritardo con molti meno bug vince su roba veloce ma buggy che arriva prima sul mercato. A volte il contrario. Devi guardare le statistiche nel tuo campo specifico e quanta direzione vuole giocare.

Alcuni tipi di bug potrebbero essere così improbabili da essere realizzati o da superare qualsiasi test di sanità mentale iniziale, dal momento che statisticamente non vale la pena dedicare tempo a creare ulteriori test specifici. Ma a volte il costo di un bug è così grande (medico, nucleare, ecc.) Che un'azienda deve fare una scommessa perdente (simile all'acquisto di un'assicurazione). Molte app non hanno costi di fallimento così elevati e quindi non necessitano di una copertura assicurativa antieconomica più elevata. Altri lo fanno.


3
Buona risposta. Uno dei pochi che risponde davvero alla mia domanda originale. Mi sono immerso nel mondo dei test da quando ho scritto questo post (mi piace tra l'altro.) Ho bisogno di capirlo di più prima di poter veramente sapere quando usarlo (o meno). Per molti dei motivi indicati qui, preferirei usarlo sempre. Ma alla fine dipenderà da quanto più velocemente ci riuscirò, perché alla fine è una scommessa del mio tempo, che è sotto il controllo della mia azienda / cliente, e spesso si concentrano sugli angoli inferiori del triangolo del progetto: en. wikipedia.org/wiki/Project_triangle
Ken Pespisa,

10

Il mio consiglio è di testare solo il codice che si desidera funzionare correttamente.

Non testare il codice che si desidera essere buggy e causare problemi per te lungo la strada.


9
Mi ricorda il detto del mio dentista: non devi usare il filo interdentale per tutti i denti, solo quelli che vuoi conservare.
Ken Pespisa,

Confesso che è ciò che mi ha fatto pensare. ;-)
Nick Hodges,

8

Mi chiedo spesso se dovrei provare un approccio TDD. Sembra una buona idea, ma onestamente non posso mai giustificare il lavoro extra in questione.

TDD e Unit Testing non sono la stessa cosa.

È possibile scrivere codice, quindi aggiungere test unitari in seguito. Questo non è TDD, ed è molto lavoro extra.

TDD è la pratica della codifica in un ciclo di luce rossa. Luce verde. Iterazioni di refactor.

Ciò significa scrivere test per il codice che non esiste ancora, guardare i test fallire, correggere il codice per far funzionare i test, quindi rendere il codice "giusto". Questo spesso ti fa risparmiare lavoro

Uno dei vantaggi di TDD è che riduce la necessità di pensare alle curiosità. Cose come gli errori off-by-one scompaiono. Non è necessario andare a caccia attraverso la documentazione API per scoprire se l'elenco che restituisce inizia da 0 o 1, basta farlo.


Potresti approfondire come scompaiono gli errori off-by-one? Stai dicendo che puoi ottenere più rapidamente la tua risposta se l'indice di un array è basato su zero o basato su un test piuttosto che cercare attraverso la documentazione? Mi sembra improbabile - Sono abbastanza veloce su Google :)
Ken Pespisa l'

1
In realtà, scrivere TDD è un modo eccellente per esplorare un'API (inclusa una base di codice legacy, ai fini della funzionalità di documentazione).
Frank Shearar,

È anche molto utile se l'API dovesse mai cambiare ... Improvvisamente hai dei test falliti :-)
bitsoflogic

@Ken Pespisa, è decisamente più veloce: scrivi il codice in base a se pensi che sia 0 o 1, eseguilo, correggilo se necessario. Il più delle volte, avrai ragione e avresti saltato la necessità di cercarlo, se sbagli lo sai entro 10 secondi.
Paul Butcher,

Vantaggio molto interessante. In un certo senso mi piace.
Ken Pespisa,

3

Ho lavorato su un sistema in cui abbiamo testato quasi tutto. Le esecuzioni importanti per i test sono state il codice di output PDF e XLS.

Perché? Siamo stati in grado di testare le parti che hanno raccolto i dati e costruito il modello utilizzato per creare l'output. Siamo stati anche in grado di testare le parti che hanno capito quali parti del modello sarebbero andate ai file PDF. Non siamo stati in grado di verificare se il PDF sembrava ok perché era totalmente soggettivo. Non siamo stati in grado di testare che tutte le parti di un PDF fossero leggibili per un utente normale perché anche questo era soggettivo. O se la scelta tra barra e grafici a torta era corretta per il set di dati.

Se l'output sarà soggettivo, c'è un piccolo test unitario che puoi fare per quello che vale la pena.


In realtà, questo tipo di test è probabilmente "test di integrazione". E sì, i test di integrazione sono molto più difficili dei test unitari e uno dei motivi è che a volte le regole per ciò che è "corretto" sono molto complicate o addirittura soggettive.
sleske,

2

Per molte cose, un "test di scrittura-poi-manuale" non richiede più tempo rispetto alla scrittura di un paio di test. Il risparmio di tempo deriva dalla possibilità di rieseguire quei test in qualsiasi momento.

Pensaci: se hai una buona copertura delle funzionalità con i tuoi test (da non confondere con la copertura del codice), e diciamo che hai 10 funzionalità - facendo clic su un pulsante significa che hai circa 10 ripetitori dei test ... mentre ti siedi e sorseggi il tuo caffè.

Inoltre, non è necessario testare i minutae. Puoi scrivere test di integrazione che coprono le tue funzionalità se non vuoi scendere ai dettagli grintosi ... IMO, alcuni test unitari sono troppo dettagliati testando la lingua e la piattaforma e non il codice.

TL; DR Non è mai davvero appropriato perché i benefici sono semplicemente troppo buoni.


2

Due ottime risposte che ho trovato sono qui:

  1. Quando test unitario vs test manuale
  2. Cosa non testare quando si tratta di unit test?

Le giustificazioni per evitare il sovraccarico percepito:

  • Risparmio immediato di tempo / costi per la tua azienda
  • Potenziale risparmio di tempo / costi nella risoluzione dei problemi / manutenibilità / estensione a lungo termine anche dopo che te ne sei andato.

Non vorresti lasciare un ottimo prodotto dalla tua parte come prova della qualità del tuo lavoro? Parlando in termini egoistici, non è meglio per te che lo fai?


1
Buona domanda alla fine. Sono orgoglioso del mio lavoro, assolutamente, e le mie applicazioni funzionano molto bene (se posso essere così audace). Ma hai ragione: potrebbero essere ancora meglio con il supporto di alcuni test. Penso che il mio take away qui sia quello di cercare di inserirmi nel maggior numero possibile di test utili nel tempo in cui devo lavorare al progetto e senza essere troppo ossessionato dalla copertura del codice.
Ken Pespisa,

1

Gli sviluppatori professionisti scrivono unit test perché, a lungo termine, fanno risparmiare tempo. Prima o poi testerai il tuo codice e, in caso contrario, i tuoi utenti lo faranno, e se dovrai correggere i bug in seguito, sarà più difficile da correggere e avranno più effetti a catena.

Se stai scrivendo codice senza test e senza bug, allora va bene. Non credo che tu possa scrivere un sistema non banale con zero bug, quindi suppongo che lo stai testando in un modo o nell'altro.

I test unitari sono anche cruciali per prevenire le regressioni quando si modifica o si esegue il refactoring del codice precedente. Non dimostrano che la tua modifica non ha violato il vecchio codice ma ti danno molta fiducia (purché passino ovviamente :))

Non vorrei tornare indietro e scrivere un'intera serie di test per il codice che hai già spedito, ma la prossima volta che devi modificare una funzione ti suggerirei di provare a scrivere test per quel modulo o classe, ottenere la tua copertura fino al 70% + prima di applicare qualsiasi modifica. Vedi se ti aiuta.

Se lo provi e puoi onestamente dire che non è stato d'aiuto, allora è abbastanza giusto, ma penso che ci siano abbastanza prove del settore che ti aiutano a far valere almeno la pena di te mentre provi l'approccio.


Mi piacciono i pensieri sulla prevenzione delle regressioni e sull'aggiunta di fiducia. Questi sono esattamente i motivi per cui vorrei aggiungere dei test.
Ken Pespisa,

1

Sembra che la maggior parte delle risposte siano pro-TDD, anche se la domanda non era su TDD ma sui test unitari in generale.

Non esiste una regola completamente oggettiva dietro cosa testare l'unità o non testare l'unità. Ma ci sono un paio di volte in cui sembra che molti programmatori non testino l'unità:

  1. Metodi privati

A seconda della tua filosofia OOP, potresti creare metodi privati ​​per separare le routine complesse dai tuoi metodi pubblici. I metodi pubblici sono generalmente intesi per essere chiamati in molti luoghi diversi e usati spesso, e i metodi privati ​​sono realmente chiamati solo da uno o due metodi pubblici in una classe o modulo per qualcosa di molto specifico. Di solito è sufficiente scrivere unit test per metodi pubblici ma non i metodi privati ​​sottostanti che fanno accadere parte della magia. Se qualcosa va storto con un metodo privato, i test delle unità del metodo pubblico dovrebbero essere sufficienti per rilevare questi problemi.

  1. Le cose che già conosci dovrebbero funzionare (o cose testate da qualcun altro)

Molti nuovi programmatori si oppongono a questo quando stanno imparando a testare per la prima volta e pensano di dover testare ogni singola riga in esecuzione. Se si utilizza una libreria esterna e la sua funzionalità è ben testata e documentata dai suoi autori, di solito è inutile testare la funzionalità specifica nei test unitari. Ad esempio, qualcuno potrebbe scrivere un test per assicurarsi che il proprio modello ActiveRecord persista il valore corretto per un attributo con un callback "before_save" nel database, anche se quel comportamento stesso è già stato accuratamente testato in Rails. I metodi che il callback sta chiamando, forse, ma non il comportamento di callback stesso. Qualsiasi problema di fondo con le librerie importate sarebbe meglio rivelato attraverso test di accettazione, piuttosto che unit test.

Entrambi potrebbero applicarsi se stai facendo TDD o meno.


0

Ken, io e molti altri sviluppatori là fuori siamo giunti alla stessa conclusione di te diverse volte nel corso della nostra carriera.

La verità che credo scoprirai (come molti altri) è che l'investimento iniziale di scrivere test per la tua applicazione può sembrare scoraggiante, ma se scritti bene e mirati nelle parti corrette del tuo codice, possono davvero risparmiare un sacco di tempo.

Il mio grosso problema era con i framework di test disponibili. Non ho mai avuto la sensazione che fossero quello che stavo cercando, quindi ho appena lanciato la mia soluzione molto semplice. Mi ha davvero aiutato a portarmi al "lato oscuro" dei test di regressione. Condividerò uno pseudo frammento di base di ciò che ho fatto qui, e spero che tu possa trovare una soluzione che funzioni per te.

public interface ITest {
    public string Name {
        get;
    }
    public string Description {
        get;
    }
    public List<ITest> SubTests {
        get;
    }
    public TestResult Execute();
}

public class TestResult {
    public bool Succesful {
        get;
        set;
    }

    public string ResultMessage {
        get;
        set;
    }

    private Dictionary<ITest, TestResult> subTestResults = new Dictionary<ITest, TestResult>();
    public Dictionary<ITest, TestResult> SubTestResults {
        get {
            return subTestResults;
        }
        set {
            subTestResults = value;
        }
    }
}

L'unica parte difficile dopo è capire quale livello di granularità pensi sia il miglior "bang for the buck" per qualunque progetto tu stia facendo.

Costruire una rubrica richiederà ovviamente molto meno test di un motore di ricerca aziendale, ma i fondamenti non cambiano davvero.

In bocca al lupo!


Penso che col tempo capirò quale livello di granularità è il migliore. È bello sentire da altri che stanno regolarmente creando test che li avvicinano sensibilmente e non scrivono roboticamente test per ogni risultato immaginabile. La mia prima introduzione ai test è stata a quel tipo di livello in cui tutto deve essere testato. In effetti, l'intero concetto di TDD sembra seguire quel mantra.
Ken Pespisa,

Penso che potresti trarre vantaggio dall'utilizzo di un Framework come SubSpec (ispirato a BDD), in modo che ti permetta di ottenere l'isolamento Assert ("SubTest") mentre condividi la configurazione del contesto.
Johannes Rudolph,
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.