Abbiamo bisogno di registrazione quando facciamo TDD?


41

Quando eseguiamo il ciclo rosso, verde e refattore dovremmo sempre scrivere il codice minimo per superare il test. Questo è il modo in cui mi è stato insegnato il TDD e il modo in cui quasi tutti i libri descrivono il processo.

Ma per quanto riguarda la registrazione?

Onestamente ho usato raramente la registrazione in un'applicazione a meno che non ci fosse qualcosa di veramente complicato che stava accadendo, tuttavia, ho visto numerosi post che parlano dell'importanza della registrazione corretta.
Quindi, a parte la registrazione di un'eccezione, non potrei giustificare la reale importanza della registrazione in un'applicazione testata adeguata (test di unità / integrazione / accettazione).

Quindi le mie domande sono:

  1. Dobbiamo registrarci se stiamo facendo TDD? un test fallito non rivelerà cosa c'è di sbagliato nell'applicazione?
  2. Dovremmo aggiungere test per il processo di registrazione in ciascun metodo in ogni classe?
  3. Se ad esempio alcuni livelli di registro sono disabilitati nell'ambiente di produzione, ciò non introdurrà una dipendenza tra i test e l'ambiente?
  4. Le persone parlano di come i log facilitano il debug, ma uno dei principali vantaggi di TDD è che so sempre cosa c'è che non va a causa di un test fallito.

C'è qualcosa che mi manca là fuori?


5
Penso che la registrazione sia il caso speciale di così tante regole. Una classe / funzione dovrebbe fare solo una cosa e una cosa ... ad eccezione della registrazione. Le funzioni dovrebbero preferibilmente essere pure, ad eccezione della registrazione. Così via. La registrazione infrange le regole.
Phoshi,

1
La registrazione non è per lo più ortogonale a qualsiasi metodologia di sviluppo SW utilizzata? Quindi forse dovresti limitarlo e chiedere: abbiamo bisogno di casi di test per la registrazione quando facciamo TDD?
hyde,

Risposte:


50

1) Dobbiamo registrarci se stiamo facendo TDD? un test fallito non rivelerà cosa c'è di sbagliato nell'applicazione?

Ciò presuppone che tu abbia tutti i test possibili richiesti dall'applicazione, il che è raramente vero. I registri ti aiutano a rintracciare i bug per cui non hai ancora scritto i test.

2) Dovremmo aggiungere test per il processo di registrazione in ciascun metodo in ogni classe?

Se il logger stesso viene testato, non dovrebbe essere testato nuovamente in ogni classe, in modo simile ad altre dipendenze.

3) Se alcuni livelli di registro sono disabilitati nell'ambiente di produzione, ad esempio, ciò non introdurrà una dipendenza tra i test e l'ambiente?

Gli umani (e gli aggregatori di registri) dipendono dai registri, i test non dovrebbero dipendere da essi. In genere esistono diversi livelli di registro e alcuni vengono utilizzati nella produzione e alcuni livelli aggiuntivi vengono utilizzati nello sviluppo, in modo simile a:

"Il livello di registro di Rails è informazioni in modalità di produzione e debug in sviluppo e test" - http://guides.rubyonrails.org/debugging_rails_applications.html

Altre applicazioni usano un approccio simile.

4) Le persone parlano di come i log facilitano il debug, ma uno dei principali vantaggi di TDD è che so sempre cosa c'è che non va a causa di un test fallito.

I bug di produzione avranno superato tutti i test, quindi potrebbe essere necessario qualche altro riferimento per indagare su questi problemi.


26
Anche un TDD perfettamente eseguito rigorosamente non impedirà problemi di produzione con prestazioni, interazione del sistema, interazione di terze parti. Anche i problemi di concorrenza sono molto difficili da coprire completamente tramite test. Una copertura del test al 100% "solo" significa che il 100% del codice è stato eseguito, non è corretto in tutti gli stati o ambienti.
Holstebroe,

34

La registrazione è utile per spiegare il comportamento non eccezionale di un'applicazione:

I registri eventi registrano gli eventi che si verificano nell'esecuzione di un sistema al fine di fornire una pista di controllo che può essere utilizzata per comprendere l'attività del sistema e diagnosticare i problemi. Sono essenziali per comprendere le attività di sistemi complessi, in particolare nel caso di applicazioni con scarsa interazione dell'utente (come le applicazioni server ) ...

Indipendentemente dal modo in cui l'applicazione è stata testata e indipendentemente dalle eccezioni registrate, i suoi utenti possono chiedere,

l'output del tuo programma è 0 mentre ci aspettavamo che fosse 1, perché?

È necessario il logging per verificare quale sia stata la configurazione dell'applicazione, i parametri e altri dettagli di runtime per spiegare il suo comportamento (non eccezionale).

Dal punto di vista sopra, la registrazione è più orientata al supporto che allo sviluppo. Dopo che l'applicazione è attiva, è auspicabile che qualcun altro gestisca le domande degli utenti, per consentire ai programmatori di concentrarsi su un ulteriore sviluppo.

La registrazione di ciò che l'applicazione fa consente a qualcun altro di comprendere il comportamento del programma senza scavare nel codice e senza distrarre gli sviluppatori dalle richieste di spiegare cosa sta succedendo.


5
+1 per "la registrazione è più orientata al supporto". Colpisci davvero l'unghia sulla testa.
Tibos,

1
+1 per "comportamento non eccezionale" e anche per "la registrazione è più orientata al supporto". Ma potresti modificare la tua risposta per elencare la fonte del paragrafo che citi?
logc

La fonte @logc della citazione è indicata dal link nella prima parola qui, "Registrazione" - se fai clic su di essa, porterai all'articolo di Wikipedia: en.wikipedia.org/wiki/Logfile
gnat

16

La maggior parte delle risposte qui si concentra sull'aspetto della correttezza. Ma la registrazione ha anche uno scopo diverso: la registrazione può essere un modo per raccogliere dati rilevanti. Quindi, anche quando il sistema funziona senza errori, un registro può dire perché è lento. Anche con una copertura completa dei test di tutti gli aspetti, una suite di test non lo dirà.

Ovviamente un sistema critico per le prestazioni può / dovrebbe fornire metriche prestazionali chiave ad alcune dashboard operative, ma la registrazione "classica" può fornire un diverso livello di dettaglio.


2
Inoltre, non dimenticare la registrazione a fini di audit trail. O fatturazione. O vari tipi di statistiche. O la registrazione degli eventi per la corrispondenza con altri tipi di statistiche di altri sistemi.
PlasmaHH,

La profilazione non è qualcosa che faresti senza la registrazione? O intendi semplicemente che potresti registrare continuamente i risultati della profilazione?
Bergi,

@Bergi: dipende interamente dal funzionamento dell'applicazione. Se si tratta, ad esempio, di un'applicazione Web, la registrazione del tempo di servizio di ciascuna richiesta e, successivamente, il tentativo di raggruppare quegli eventi per i "cattivi performer" potrebbero funzionare anche.
PlasmaHH,

La profilazione di @Bergi avviene nello sviluppo, ma ci sono effetti sui sistemi live da tenere a mente, l'uso dei dischi può rallentare, la CPU può essere più caricata, i servizi potrebbero non rispondere in tempo, i thread paralleli potrebbero incorrere in problemi di blocco ...
johannes,

L'auditing di @PlasmaHH fa parte dei requisiti fondamentali e deve essere coperto da test. Nella maggior parte dei casi non lo eseguo su percorsi di registrazione "normali". La registrazione normale potrebbe non riuscire, il controllo no. "varie statistiche" che ho raccolto sotto esibizione;)
johannes

8
  1. A meno che tu non abbia una copertura di prova al 100%, che di solito non è il caso, non puoi sapere che il tuo software non andrà mai in crash (EDIT: e - come detto nei commenti - anche se lo fa, qualcosa di indipendente dal tuo software potrebbe causare un incidente); è come pensare di poter fare un software che non ha assolutamente alcun bug (nemmeno la NASA può farlo). Quindi, per lo meno, è necessario registrare i possibili errori nel caso in cui il programma si blocchi in modo da poter sapere perché.

  2. La registrazione dovrebbe essere effettuata da una libreria esterna o da un framework interno a seconda della tecnologia che si sta utilizzando. Quello che voglio dire è che dovrebbe essere qualcosa che è già stato testato prima e che non è necessario testare te stesso. È eccessivo verificare che ogni metodo registri le cose che dovrebbe.

  3. I registri non sono pensati per i test, non dovrebbe esserci alcuna dipendenza. Detto questo, non è necessario disabilitare la registrazione per i test se ti sembra un vincolo, anche se i log dovrebbero essere conservati in un file corrispondente all'ambiente (dovresti avere un file diverso per l'ambiente di test, sviluppo e produzione Proprio alla fine).

  4. Un errore potrebbe non essere chiaro e non è sempre ovvio che cosa è andato storto quando un test TDD ha fallito. I registri dovrebbero essere più precisi. Ad esempio, se stai eseguendo un algoritmo di ordinamento e l'intero caso di test fallisce, dovresti avere dei registri per ogni singolo test dell'algoritmo che ti aiutano a individuare dove si trova effettivamente il problema.


4
Anche se hai una copertura del 100%, ce l'hai per ogni possibile cosa che può accadere? Cosa succede se la connessione di rete al database si interrompe? Le tue prove te lo diranno?
Zaccaria K,

Non puoi mai sapere che il tuo software non andrà mai in crash ANCHE se hai una copertura del 100%. Una copertura del 100%, sebbene desiderabile, fornisce molte meno informazioni sulla correttezza di quanto sembrerebbe.
Andres F.

Sì, anche tu hai ragione. Il punto è che non è possibile avere alcuna possibilità di crash. Lo modificherò.
Pierre Arlaud,

1
La modifica è ancora errata. Anche se hai una copertura del test al 100%, potrebbe esserci un bug nel tuo codice (non è necessario incolpare cause esterne). I test NON implicano il funzionamento del codice; l'unica cosa che implicano con certezza è che non sei riuscito a scrivere un test che trova un bug :) La copertura del test è una metrica importante, ma non è direttamente correlata all'assenza di bug.
Andres F.

4
È banale provare che "copertura del test al 100% che passa! = Bug free". Controesempio: add(x, y) = 2(restituisce sempre 2). Il seguente test passa e fornisce una copertura completa: assert(2 == add(1,1)). Copertura del test al 100% per una funzione con errori :)
Andres F.

8

La risposta breve alla tua domanda principale è: come regola generale, i bug nel tuo codice NON saranno esposti da TDD. Alcuni potrebbero, idealmente molti, ma l'assenza di test falliti non implica l'assenza di bug. Questa è una massima molto importante nei test del software.

Dal momento che non si può sapere se si avrà un comportamento errato nel proprio sistema, magari in rare condizioni, la registrazione è uno strumento utile che potrebbe aiutare a capire cosa c'è che non va quando le cose inevitabilmente vanno male.

Registrazione e TDD affrontano diverse preoccupazioni.


5

Sì, in generale è necessario il log.

La registrazione non riguarda il debug. Bene, OK, una parte della registrazione a volte riguarda il debug e puoi saltare quella parte se non ti serve durante lo sviluppo.

Ma la parte più importante della registrazione riguarda la manutenibilità. La registrazione ben progettata potrebbe rispondere alle seguenti domande:

  • L'applicazione è ancora viva e vegeta? (Registrando un battito cardiaco ogni 1000 secondi.)
  • Le prestazioni dell'applicazione sono cambiate negli ultimi 10 mesi? (Registrando le statistiche sull'esecuzione dei casi d'uso.)
  • Il carico dell'appliation è cambiato negli ultimi 10 mesi? (Registrando il numero di richieste per tipo di richiesta.)
  • Qualcuno delle nostre interfacce ha cambiato le loro caratteristiche prestazionali?
  • La nuova versione provoca una diversa caratteristica di utilizzo verso alcuni dei sottosistemi?
  • Siamo sotto attacco DoS ?
  • Che tipo di errori stanno accadendo?

Tutto ciò può essere ottenuto registrando. E sì, dovrebbe essere pianificato, progettato e testato, preferibilmente automatico.

La registrazione è una funzionalità che merita il trattamento, proprio come altre funzionalità.


4

TL; DR: registrazione e TDD sono ortogonali. Avere uno non ha alcun rapporto con il bisogno dell'altro

Dobbiamo registrarci se stiamo facendo TDD? un test fallito non rivelerà cosa c'è di sbagliato nell'applicazione?

In generale, la maggior parte della registrazione che ho implementato e che ho visto implementato è stata per la risoluzione dei problemi operativi, non per il debug dello sviluppo (sebbene possa aiutare). Il pubblico principale per questa registrazione sono gli amministratori e gli operatori che gestiscono i tuoi server, supportano le persone a cui sono stati inviati registri per l'analisi e i clienti che desiderano esaminare i registri e provare a capire cosa sta succedendo.

Questi registri sono lì per aiutare a risolvere i problemi che riguardano in gran parte i punti di integrazione. Ciò può includere servizi di rete (database, soap, ecc.), Risorse locali (disco, memoria, ecc.), Dati errati (input del cliente, origini dati errate / danneggiate, ecc.), Ecc. Acquisizione di eccezioni, errori di registrazione e persino registrazione informativa (impostazioni, configurazioni, ecc.) possono essere utili per la risoluzione dei problemi.

Dovremmo aggiungere test per il processo di registrazione in ciascun metodo in ogni classe?

Aggiungi test ovunque sia necessario per testare la registrazione. Se si dispone di chiamate ad hoc per disconnettersi, è necessario verificarle. Tuttavia, se si implementano la registrazione e i test dei registri utilizzando la programmazione orientata agli aspetti o la meta-programmazione, ciò potrebbe ridurre l'onere dei test.

Se ad esempio alcuni livelli di registro sono disabilitati nell'ambiente di produzione, ciò non introdurrà una dipendenza tra i test e l'ambiente?

Se stai scrivendo il tuo codice utilizzando IoC e fai uso di simulazioni, dovresti essere in grado di testare efficacemente tutte le tue registrazioni senza fare affidamento su una particolare configurazione ambientale.


3

TDD generalmente aiuta a ridurre i bug di codifica. Aiuta molto meno con i bug con le specifiche o semplicemente fraintendimenti su come funzionano le cose.

"Oh? Puoi ricevere un messaggio di dati prima di ottenere la conferma dell'accesso riuscito? Non l'ho mai saputo, beh non lo gestirà!" ... Questo genere di cose. La registrazione è molto utile per dirti che cosa il software ha cercato di fare in modo da poter individuare ciò che hai fatto di sbagliato.


2

Nella mia esperienza, quando non eseguiamo TDD, viene aggiunto all'applicazione un ottimo livello di registrazione. Quindi il livello di incertezza diventa alto, quindi aggiungiamo la registrazione per vedere cosa sta succedendo.

Considerando che quando faccio TDD (o forse test ogni volta) mi ritrovo ad aggiungere molte meno istruzioni di registro. Questo a sua volta significa meno LOC e può (non sempre) influire sulle prestazioni.

Tuttavia, nella maggior parte dei casi aggiungiamo log di immissione-uscita per funzioni in modo semi-automatico presso la mia azienda, indipendentemente dal metodo di sviluppo. Come so questo è stato considerato obbligatorio per l'analisi dei problemi di produzione.

Esempio potrebbero essere i metodi di un bean di servizio EJB presenti nell'interfaccia pubblica. Un altro potrebbe essere un caso in cui una funzione esegue calcoli complessi. Può essere molto utile inserire cifre nel metodo (ad esempio è possibile scrivere un test unitario per tornare all'argomento generale a portata di mano).


potresti espandere i motivi per cui aggiungi i log di immissione-uscita per le funzioni? perché è richiesto dalla tua azienda?
moscerino il

si assolutamente. spero sia meglio ora.
dbalakirev,
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.