2009-11-25 18 views
27

Sono stato un po 'di volte da Java assert dichiarazioni che non sono fallite nella suite di test JUnit perché le asserzioni non erano abilitate nell'istanza JVM di JUnit. Per essere chiari, si tratta di asserzioni "black box" all'interno delle implementazioni (controllo invarianti, ecc.) Non delle asserzioni definite dai test JUnit stessi. Certo, mi piacerebbe cogliere eventuali errori di asserzione nella suite di test.JUnit: abilita le asserzioni nella classe in prova

La soluzione più ovvia è quella di essere molto attenti utilizzare -enableassertions ogni volta che corro JUnit, ma preferirei una soluzione più robusta. Un'alternativa è quella di aggiungere il seguente test per ogni classe di test:

@Test(expected=AssertionError.class) 
    public void testAssertionsEnabled() { 
    assert(false); 
    } 

Esiste un modo più automatico per ottenere questo risultato? Un'opzione di configurazione a livello di sistema per JUnit? Una chiamata dinamica che potrei inserire nel metodo setUp()?

+1

Solo una domanda di carattere generale. Se vuoi veramente testare il tuo codice, non dovresti testare e senza le affermazioni abilitate? Una cosa è che le affermazioni sono davvero buone ** perché sta introducendo effetti collaterali inaspettati. –

+0

btw. come stai gestendo i JUnit Testcases? Se hai qualche gestore di build (formica, esperto), dovrebbe essere banale aggiungere questo switch di default – jitter

+0

@Alexander: non è una cattiva idea. @jitter: certo che hai ragione. Maven sembra abilitare le asserzioni di default. Non avevo notato prima che Eclipse avesse un'impostazione di preferenza per questo. Il problema è che questo tipo di impostazioni può cambiare alle tue spalle ... –

risposta

5

propongo tre possibili correzioni (semplice?) Che lavorano per me, dopo un rapido test (ma potrebbe essere necessario per verificare gli effetti collaterali dell'utilizzo di un-inizializzatore-blocco statico)

1.) Inserisci una statica blocco -initializer a quei casi di test che si basano su affermazioni di essere abilitato

import .... 
public class TestXX.... 
... 
    static { 
     ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true); 
    } 
    ... 
    @Test(expected=AssertionError.class) 
    ... 
... 

2.) Creare una base di classe che tutti i test-classi estendono che hanno bisogno di asserzioni abilitate

public class AssertionBaseTest { 
    static { 
     //static block gets inherited too 
     ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true); 
    } 
} 

3.) Creare una suite di test che gestisce tutta la tua prova

import org.junit.runner.RunWith; 
import org.junit.runners.Suite; 

@RunWith(Suite.class) 
@Suite.SuiteClasses({ 
    //list of comma-separated classes 
    /*Foo.class, 
    Bar.class*/ 
}) 
public class AssertionTestSuite { 
    static { 
     //should run before the test classes are loaded 
     ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true); 
    } 
    public static void main(String args[]) { 
     org.junit.runner.JUnitCore.main("AssertionTestSuite"); 
    } 
} 
+0

+1 Gemma Java nascosta molto bella. –

+1

Questo non funziona nel mio caso. Si basa sull'ordine di caricamento delle classi. –

+2

Siamo spiacenti, ma questo non funzionerà come previsto. Le asserzioni devono essere abilitate durante il caricamento e l'inizializzazione di una classe e l'impostazione dello stato di asserzione predefinito sul caricatore di classi influisce solo sulle classi, che vengono caricate in un secondo momento. – jarnbjo

1

Come un mio amico dice ... perché prendere il tempo di scrivere un'asserzione se si sta solo andando a spegnerlo?

Dato che la logica tutta affermare dichiarazioni dovrebbero diventare:

if(!(....)) 
{ 
    // or some other appropriate RuntimeException subclass 
    throw new IllegalArgumentException("........."); 
} 

per rispondere alla tua domanda un modo probabilmente si desidera :-)

import org.junit.BeforeClass; 
import org.junit.runner.RunWith; 
import org.junit.runners.Suite; 


@RunWith(Suite.class) 
@Suite.SuiteClasses({ 
     FooTest.class, 
     BarTest.class 
     }) 
public class TestSuite 
{ 
    @BeforeClass 
    public static void oneTimeSetUp() 
    { 
     ClassLoader.getSystemClassLoader().setDefaultAssertionStatus(true); 
    } 
} 

quindi eseguire il test suite piuttosto che ogni test. Ciò dovrebbe (funziona nei miei test, ma non ho letto i componenti interni del codice del framework JUnit) e lo stato di asserzione viene impostato prima che venga caricata una qualsiasi delle classi di test.

+0

A meno che l'asserzione non abbia mostrato di rallentare il codice fino al punto in cui si trattava di un problema, avrei preferito averli sempre. Condizioni preliminari/condizioni postali e qualsiasi altro tipo di affermazione di affermazione - se si è preso il tempo di scriverlo perché spegnerlo? – TofuBeer

+0

Se si tratta di una precondizione, la mia argomentazione è che non è degno di un'asserzione e deve essere controllato e generato come UnlegalArgumentException o quale sia l'eccezione appropriata per tale precondizione. Le post-condizioni sono totalmente degne di affermazione, assumendo che stia controllando qualcosa di più di @NotNull. – Trejkaz

+0

Le asserzioni sono comunque utili per i metodi privati, in cui si desidera verificare le condizioni preliminari durante lo sviluppo ma non in produzione. Preferisci le eccezioni sulle interfacce pubbliche a meno che non ci sia un buon motivo per non farlo. – SigmaX

4

In alternativa, è possibile compilare il codice in modo che le asserzioni non possano essere disattivate. Sotto Java 6, è possibile utilizzare "fa.jar – Force assertion check even when not enabled", una piccola modifica.

+0

Fantastica idea! Però non funzionerà per me, se non funziona in Eclipse. –

21

In Eclipse si può andare a WindowsPreferencesJavaJUnit, che ha la possibilità di aggiungere -ea ogni volta si crea una nuova configurazione di lancio. Aggiunge l'opzione -ea anche alla configurazione di debug.

Il testo completo accanto a una casella di controllo è

Add '-ea' per argomenti VM quando si crea un nuovo lancio JUnit configurazione

+0

hai qualche tipo di plugin per test di unità in Eclipse? Non riesco a trovare questa opzione. –

+0

No, fa parte dell'installazione standard di Eclipse – RAbraham

+0

Quale versione di Eclipse usi? –

Problemi correlati