Domanda

Mi chiedo perché la parola chiave assert sia così poco utilizzata in Java? Non li ho quasi mai visti usati, ma penso che siano un'ottima idea. Preferisco di gran lunga la brevità di:

assert param != null : "Param cannot be null";

alla verbosità di:

if (param == null) {
    throw new IllegalArgumentException("Param cannot be null");
}

Il mio sospetto è che siano sottoutilizzati perché

  • Sono arrivati ??relativamente tardi (Java 1.4), quando ormai molte persone avevano già stabilito il loro stile / abitudine di programmazione Java
  • Sono disattivati ??in fase di esecuzione per impostazione predefinita
È stato utile?

Soluzione

asserzioni sono, in teoria, per testare invariants , ipotesi che deve essere vero affinché il codice venga completato correttamente.

L'esempio mostrato sta testando un input valido, che non è un uso tipico di un'asserzione perché è, generalmente, fornito dall'utente.

Le asserzioni non vengono generalmente utilizzate nel codice di produzione perché c'è un sovraccarico e si presume che le situazioni in cui gli invarianti falliscono siano state rilevate come errori di codifica durante lo sviluppo e il test.

Il tuo punto su di loro in arrivo "in ritardo" a java è anche un motivo per cui non sono più visti.

Inoltre, i framework di unit test permettono che alcune delle affermazioni programmatiche siano esterne al codice testato.

Altri suggerimenti

È un abuso delle affermazioni usarle per testare l'input dell'utente. Lanciare un IllegalArgumentException su input non validi è più corretto, in quanto consente al metodo di chiamata di rilevare l'eccezione, visualizzare l'errore e fare tutto ciò che è necessario (chiedere di nuovo input, uscire, qualunque cosa).

Se quel metodo è un metodo privato all'interno di una delle tue classi, l'asserzione va bene, perché stai solo cercando di assicurarti di non passargli accidentalmente un argomento nullo. Esegui il test con asserzioni attivate e quando hai testato tutti i percorsi e non hai attivato l'asserzione, puoi disattivarle in modo da non sprecare risorse su di esse. Sono utili anche come commenti. Un assert all'inizio di un metodo è una buona documentazione per i manutentori che dovrebbero seguire determinate condizioni preliminari e un assert alla fine con un postcondition documenta quale dovrebbe essere il metodo facendo. Possono essere utili quanto i commenti; inoltre, perché con le asserzioni in corso, TESTANO effettivamente ciò che documentano.

Le asserzioni sono per il test / debugging, non per il controllo degli errori, motivo per cui sono disattivate per impostazione predefinita: scoraggiare le persone dall'utilizzare asserzioni per convalidare l'input dell'utente.

Da Programmazione con asserzioni

  

Per impostazione predefinita, le asserzioni sono disabilitate in fase di esecuzione. Due opzioni della riga di comando consentono di abilitare o disabilitare in modo selettivo le asserzioni.

Ciò significa che se non si ha il controllo completo sull'ambiente di runtime, non è possibile garantire che venga chiamato anche il codice di asserzione. Le asserzioni devono essere utilizzate in un ambiente di test, non per il codice di produzione. Non è possibile sostituire la gestione delle eccezioni con asserzioni perché se l'utente esegue l'applicazione con asserzioni disabilitate (il predefinito ), tutto il codice di gestione degli errori scompare.

In "Java efficace", Joshua Bloch ha suggerito (nell'argomento "Verifica i parametri per la validità") che (una specie di semplice regola da adottare), per metodi pubblici, dovremo convalidare gli argomenti e gettare le necessarie eccezioni se trovato non valido, e per metodi non pubblici (che non sono esposti e l'utente come l'utente dovrebbe garantirne la validità), possiamo invece utilizzare l'asserzione.

YC

@Don, sei frustrato dal fatto che l'asserzione sia disattivata per impostazione predefinita. Anche io, e quindi ho scritto questo piccolo plugin javac che li incorpora (cioè emette il bytecode per se (! Expr) lancia Ex piuttosto che questo stupido assert bytecode.

Se includi fa.jar nel tuo percorso di classe durante la compilazione del codice Java, farà la sua magia e poi lo dirà

Note: %n assertions inlined.

@see http://smallwiki.unibe.ch/adriankuhn/javacompiler/forceassertions e in alternativa su github https://github.com/akuhn/javac

Non sono sicuro del motivo per cui dovresti preoccuparti di scrivere assert e quindi sostituirli con un'istruzione if if condition standard, perché non scrivere semplicemente le condizioni come se in primo luogo?

Gli assegni sono solo per i test e hanno due effetti collaterali: binari più grandi e prestazioni degradate quando abilitati (motivo per cui puoi disattivarli!)

Gli avvisi non devono essere utilizzati per convalidare le condizioni perché ciò significa che il comportamento della tua app è diverso in fase di esecuzione quando gli avvisi sono abilitati / disabilitati, il che è un incubo!

Le asserzioni sono utili perché:

  • rileva gli errori di PROGRAMMAZIONE in anticipo
  • codice documento usando codice

Considerali come auto-validazione del codice. Se falliscono, ciò significa che il programma è interrotto e deve arrestarsi. Accendili sempre durante il test dell'unità!

In The Pragmatic Programmer raccomandano persino di farli funzionare in produzione.

  

Lascia asserzioni attivate

     

Usa le asserzioni per prevenire l'impossibile.

Nota che le asserzioni generano AssertionError se falliscono, quindi non vengono catturate dall'eccezione catch.

Le asserzioni sono molto limitate: puoi testare solo condizioni booleane e devi sempre scrivere il codice per un utile messaggio di errore. Confronta questo con assertEquals () di JUnit che consente di generare un utile messaggio di errore dagli input e persino di mostrare i due input fianco a fianco nell'IDE in un runner JUnit.

Inoltre, non puoi cercare asserzioni in alcun IDE che ho visto finora, ma ogni IDE può cercare invocazioni di metodi.

In effetti sono arrivati ??in Java 1.4

Penso che il problema principale sia che quando si codifica in un ambiente in cui non si gestiscono direttamente le opzioni jvm da soli come nei server eclipse o J2EE (in entrambi i casi è possibile modificare le opzioni jvm ma è necessario effettuare una ricerca approfondita per trova dove si può fare), è più facile (intendo che richiede meno sforzi) usare if e le eccezioni (o peggio non usare nulla).

Come altri hanno affermato: le asserzioni non sono appropriate per la convalida dell'input dell'utente.

Se sei interessato alla verbosità, ti consiglio di consultare una biblioteca che ho scritto: https: // bitbucket .org / cowwoc / esigenze / . Ti consentirà di esprimere questi controlli usando pochissimo codice e genererà persino il messaggio di errore per tuo conto:

requireThat("name", value).isNotNull();

e se insisti nell'utilizzare asserzioni, puoi farlo anche tu:

assertThat("name", value).isNotNull();

L'output sarà simile al seguente:

java.lang.NullPointerException: name may not be null

tl; dr

  • Sì, utilizza i test di asserzione in produzione dove ha senso.
  • Utilizza altre librerie ( JUnit , AssertJ , Hamcrest , ecc.) piuttosto che la funzione assert integrata, se lo desideri.

La maggior parte delle altre risposte in questa pagina spingono il massimo "Le asserzioni non sono generalmente utilizzate nel codice di produzione". Sebbene sia vero nelle app per la produttività come un elaboratore di testi o un foglio di calcolo, nelle app aziendali personalizzate in cui Java è così comunemente usato, i test di asserzione in produzione sono estremamente utili e comuni.

Come molte massime nel mondo della programmazione, ciò che inizia vero in un contesto viene frainteso e poi applicato in modo errato in altri contesti.

App per la produttività

Questa massima di " Le asserzioni non sono generalmente utilizzate nel codice di produzione ", sebbene comune, non è corretta.

Test di asserzione formalizzati originati con app come un elaboratore di testi come Microsoft Word o un foglio di calcolo come Microsoft Excel . Queste app potrebbero invocare una serie di asserzioni di test di asserzione su ogni sequenza di tasti effettuata dall'utente. Tale ripetizione estrema ha influito gravemente sulle prestazioni. Pertanto, solo le versioni beta di tali prodotti in distribuzione limitata avevano abilitato le asserzioni. Quindi la massima.

App aziendali

Al contrario, nelle app orientate al business per l'immissione dei dati, il database o altri processi di elaborazione dei dati, l'uso dei test di asserzione in produzione è estremamente utile. Il colpo insignificante sulle prestazioni lo rende abbastanza pratico - e comune.

Test delle regole commerciali

La verifica delle regole aziendali in fase di esecuzione in produzione è del tutto ragionevole e deve essere incoraggiata. Ad esempio, se una fattura deve contenere sempre uno o più elementi pubblicitari, scrivere un test di asserzione rispetto al conteggio degli elementi pubblicitari della fattura maggiore di zero. Se il nome di un prodotto deve contenere almeno 3 caratteri o più, scrivere un'asserzione verificando la lunghezza della stringa. Tali test non hanno alcun impatto significativo sulle prestazioni in produzione.

Condizioni di runtime

Se l'app prevede che determinate condizioni siano sempre vere quando l'app viene eseguita in produzione, scrivi quelle aspettative nel tuo codice come test di asserzione.

Se ti aspetti che a volte tali condizioni possano ragionevolmente fallire, allora non scrivi test di asserzione. Forse gettare alcune eccezioni. Quindi prova a recuperare dove possibile.

sanity-checks

Controlli di integrità anche in fase di esecuzione in produzione è del tutto ragionevole e dovrebbe essere incoraggiato . Testare alcune condizioni arbitrarie che non si può immaginare di non essere vero ha salvato il mio bacon in innumerevoli situazioni in cui si sono verificati eventi bizzarri.

Ad esempio, testare che arrotondare un nichel (0,05) al penny ha portato a un nichel (0,05) in una determinata libreria mi ha aiutato ad essere una delle prime persone a scoprire un difetto tecnologico a virgola mobile che Apple ha spedito nel loro Rosetta durante la transizione da PowerPC a Intel. Un simile difetto nel raggiungere il pubblico sarebbe sembrato impossibile. Ma sorprendentemente, il difetto era sfuggito all'attenzione del fornitore originario, Transitive e Apple, e agli sviluppatori ad accesso anticipato che testavano le beta di Apple.

(A proposito, dovrei menzionare ... non usare mai

scroll top