2009-07-30 13 views
18

Questa non è davvero una "domanda", quindi la sto facendo in CW.Usi asserzioni?

Il

assert 

parole chiave è grande!

Dovrebbe farti sentire più sicuro del codice che hai scritto, ma fino a oggi, quando stavo creando una piccola classe di test (< 20 linee) mi rendo conto di non usarlo mai da quando è stato introdotto.

Heck! Uso a malapena il logger, che è davvero molto utile, ma non è stato fino a oggi che mi rendo conto di non usare asserzioni.

Usi asserzioni? Se no, qual è la ragione?

+2

Così le persone rispondono "sì" e "no"? Quanto è utile? Ci sono molte, molte risposte da asserire su SO, forse dovresti leggerne alcune? –

+4

Li usi Neil, nella tua normale codifica? – OscarRyz

risposta

2

No, non usarli mai. Non so perché, non ho mai preso l'abitudine.

0

Tendo a non usarli, anche se non sono sicuro del perché.

Se si esegue il test delle unità, ad esempio con nUnit, le si utilizzerà ovviamente sempre per verificare i risultati del test.

15

Mi è stato insegnato a usare molte affermazioni negli anni '90 e avevano molto senso. È una buona codifica difensiva.

Tuttavia, penso che questo sia stato superato dai test delle unità che in realtà forza il codice a funzionare e indica dove è stato interrotto. Debug afferma che qualcuno deve effettivamente eseguire il codice di debug e guardare l'interfaccia utente o i log. Il test delle unità può automatizzarlo.

+3

Durante i test, i ratti probabilmente non roderanno il cavo di comunicazione, qualcuno che gioca non esaurirà la memoria e i file di registro non riempiranno il disco rigido. Queste cose potrebbero accadere quando il tuo programma viene eseguito in un ambiente di produzione. [Hun 00] The Pragmatic Programmer – citn

+1

Quindi stai sostenendo che il debug asserisce in qualche modo di risolvere questi problemi? O stai dicendo che il debug asserisce, test di unità, ecc. Non possono risolvere questi problemi? O che tutti i test sono cattivi, quindi non farlo? –

+7

Non sono d'accordo con questa risposta. NON è stato sostituito, è stato integrato. I test unitari non sostituiscono le asserzioni. Le asserzioni sono molto utili per evitare errori di programmazione, come passare null a un metodo che non accetta nulla. È proprio lì, per i tuoi occhi, il tuo parametro NON PUO 'essere nullo, quindi non hai (se param! = Null) dappertutto ... –

14

Io li uso sempre. Sono un buon modo per mettere in pratica la filosofia "Crash early", meglio dover risolvere il motivo per cui un'affermazione è fallita piuttosto che dover affrontare un output cattivo/corrotto.

Il problema è che devi rendere l'abitudine. Raramente vedo una via di mezzo, le persone non ci sono abituate e quasi mai le usano o le persone le usano e sono disseminate rigorosamente in tutto il codice. Devi solo entrare nella mentalità di notare "Oh hey, sono implicito assumendo qualcosa qui, lasciami esplicitamente confermare 'asserire (ASSUNZIONE)'"

+1

Per quello che ho letto nella tua risposta, penso che una convalida farebbe meglio, perché in fin dei conti si dice che debbano essere rimossi sul codice di produzione. Lo scopo principale era quello di effettuare controlli costosi nel prodotto beta. – OscarRyz

+4

L'assert non dovrebbe essere rimosso nel codice di produzione ... Sono troppo utili per capire perché il processo ha esito negativo (si pensi alla propagazione nulla in 4 o 5 livelli, da dove proviene questo null?). E non farmi iniziare il successo in termini di prestazioni ... –

3

Io non li uso. I test unitari dovrebbero essere sufficienti per testare il codice. Inoltre, poiché sono disabilitati per impostazione predefinita, in genere vengono ignorati completamente. Quindi tendono a ingombrare il tuo codice con affermazioni inutili che potrebbero essere meglio espresse come commenti.

Se davvero bisogno di questo, però, alcune biblioteche hanno affermazione statica metodi che è possibile chiamare che si non essere saltati - questi sono anche molto più leggibile, perché la parola chiave assert è raro ed immediatamente può causare un "WTF "momento, ma i metodi Assert.x sono solo metodi che possono essere rintracciati. Il framework Spring, in particolare, utilizza una libreria di asserzioni.

+0

I commenti possono essere scaduti o errati, mentre un'asserzione è un contratto in codice. Non sono d'accordo che le asserzioni ingombrino il codice, e certamente non sono d'accordo sul fatto che i commenti siano migliori nell'esprimere l'affermazione. Chiunque esegua il codice per eseguire il debug dovrebbe avere delle affermazioni su. Suppongo che se non lo usi mai, la parola chiave assert è rara, ma illeggibile? D'accordo, non importa quale metodo usi per le tue asserzioni, un built-in o una libreria. – Sean

+0

Le asserzioni, poiché sono disabilitate per impostazione predefinita, hanno gli stessi problemi dei commenti di codice. Possono "essere obsoleti o semplicemente sbagliati" - perché devi esplicitamente attivarli, quindi, non sempre affermano come dovrebbero e i loro fallimenti non vengono notati fino a quando essi stessi potrebbero non essere più rilevanti. – MetroidFan2002

4

Risposta breve - Sì.

Risposta lunga: non sempre, ma abbastanza spesso. Di solito uso asserzioni per errori so che non posso fare nulla (mentre il programma è in esecuzione) e la registrazione non è realmente richiesta. Ad esempio: se devo verificare se un certo valore è fuori limite o se un puntatore è NULL anche se dovrebbe avere qualche valore.

Per altri elementi come "Analisi dei file" e "Impossibile trovare il file", di solito faccio delle eccezioni.In questo modo posso registrare l'errore e utilizzare invece un file/metodo sicuro.

E sono abbastanza d'accordo con con Falaina, si dovrebbe fare un punto da notare - "Ehi Sto facendo alcune ipotesi qui"

1

tendo a verificare la presenza di condizioni di errore e generare eccezioni, invece. Il motivo è che voglio che queste condizioni siano sempre controllate, anche in produzione, e le eccezioni forniscono una gestione più semplice della condizione fallita piuttosto che delle asserzioni.

10

Uso asserzioni per assicurarmi di non introdurre errori nel mio codice. Se so che un valore dovrebbe essere in una mappa, asserisco per quello (usando la parola chiave assert). Se so che un parametro non dovrebbe mai essere nullo, lo dico per quello. Se so che il parametro può essere nullo, allora lo controllerò e genererò l'eccezione appropriata.

L'ho letto in Code Complete o in Java efficace: le asserzioni devono essere utilizzate per rilevare errori di programmazione; devono essere utilizzate eccezioni per gestire situazioni eccezionali ma possibili. Non è necessario verificare la nullità su ogni metodo sul proprio codice se si sa che il valore non sarà nullo (come definito da un contratto), ma non fa male asserire se un valore non è nullo. Le asserzioni sono abilitate solo se si specifica il parametro -ea alla VM e non dovrebbero influire sulle prestazioni dell'applicazione se disabilitate.

Si dovrebbe usare anche più logging :-). Scopri quando utilizzare trace, debug e informazioni e assicurati di registrare tutto ciò che fa l'applicazione. Rende la vita più facile quando devi capire perché qualcosa non funziona in un ambiente di produzione.

+3

"le asserzioni dovrebbero essere utilizzate per rilevare errori di programmazione" ** esattamente ** +1 –

0

No, non li uso.

Mi è stato insegnato che gli asserzioni non devono essere utilizzati nel codice "produzione" e prima di iniziare a utilizzare qualcosa che devo rimuovere comunque, in base a ciò che ho appreso, rimango con eccezioni per convalidare le condizioni.

0

Non l'ho mai usato, ma ho avuto un tempo terribile di eseguire il debug del mio ultimo programma e, a un certo punto, il log era quando le variabili erano nulle o non contenevano i valori che mi sarei aspettato. Una volta che ho funzionato tutto ho affermato tutto il mio programma necessario per funzionare correttamente.

1

La parola chiave assert Java è piuttosto mezza assunta (è necessario eseguire il programma con l'opzione -ea riga di comando) quindi mi trovo a fare affidamento su eccezioni anziché asserzioni.

4

L'unico vero uso per le asserzioni dopo che è stato introdotto il test dell'unità è quello di comunicare l'invariante di un metodo ad altri programmatori. Ed è molto meglio farlo nel codice reale che nei commenti che ignoreranno comunque. È difficile ignorare un'affermazione!

0

No. Ma non vedo l'ora. Ero solito testare tutto con junit, ma quella era scuola, piccoli progetti senza pressione. Sono nella vita reale ora, dovrei finire questo codice ieri ....

2

Se ti piacciono gli asserti, ti piaceranno i contratti. Sono fondamentalmente l'idea di affermazioni estese a più situazioni.

2

Sì! Sempre! La parola chiave è la mia migliore amica in tutte le lingue!

Non c'è un vero motivo per non utilizzare gli asserzioni, essi garantiscono che le ipotesi di base che faccio su valori e stati di input siano confermate.

Se un assert non funziona, significa che ho bisogno di rivalutare le mie ipotesi e aggiornare il codice per gestire nuovi input esotici che non pensavo quando scrivevo la revisione corrente. Cosa c'è che non va?

Come al solito nella programmazione, è uno strumento potente solo se usato correttamente.

2

Sì, io uso afferma tutto il tempo, in fondo ogni volta che sto facendo un presupposto che:

  1. può essere controllato con un abbastanza semplice predicato.
  2. Ovviamente non è vero semplicemente leggendo il codice vicino.

Tuttavia, per afferma che sono suscettibili di avere un impatto trascurabile sulle prestazioni, io uso la funzione enforce nella programmazione D linguaggio di libreria standard invece di assert. Questo in pratica è la stessa cosa di assert, tranne che rimane in modalità di rilascio. Per asserzioni più costose, utilizzo assert, che viene rimosso dalle build in modalità rilascio.