Esegui o ignora test in modo condizionale in JUnit 4

1. Panoramica

Immaginiamo di avere un test per un codice che dipende dal sistema operativo e dovrebbe essere eseguito solo se la nostra macchina di test è in esecuzione su Linux. Se è in esecuzione su qualsiasi altro sistema operativo, vogliamo che il test non fallisca, ma venga ignorato in fase di esecuzione.

Un primo approccio potrebbe essere l'utilizzo di un paio di istruzioni if per verificare questa condizione utilizzando le proprietà della classe System . Funziona, ovviamente, ma JUnit ha un metodo più pulito ed elegante.

In questo breve tutorial, vedremo come eseguire o ignorare in modo condizionale i test in JUnit 4 utilizzando la classe Assume .

2. La classe Assume

Questa classe fornisce una serie di metodi per supportare l'esecuzione di test condizionali in base a determinate condizioni . Il nostro test verrà eseguito solo se tutte queste condizioni saranno soddisfatte. In caso contrario, JUnit salterà la sua esecuzione e la contrassegnerà come passata nel rapporto di prova . Quest'ultima è la principale differenza con la classe Assert , in cui una condizione di fallimento fa terminare il test come fallimento .

Una cosa importante da notare è che il comportamento che abbiamo descritto per la classe Assume è esclusivo del runner JUnit predefinito . Con i corridori personalizzati, le cose potrebbero essere diverse.

Infine, allo stesso modo di Assert , possiamo chiamare i metodi Assume nei metodi annotati @Before o @BeforeClass o all'interno del metodo @Test stesso.

Esaminiamo ora i metodi più utili della classe Assume mostrando alcuni esempi. Per tutti i seguenti esempi, supponiamo che getOsName () restituisca Linux.

2.1. Utilizzando assumeThat

Il metodo assumeThat () verifica che lo stato, in questo caso getOsName () , soddisfi le condizioni del matcher passato:

@Test public void whenAssumeThatAndOSIsLinux_thenRunTest() { assumeThat(getOsName(), is("Linux")); assertEquals("run", "RUN".toLowerCase()); }

In questo esempio, abbiamo verificato se getOsName () è uguale a Linux . Poiché getOsName () restituisce Linux , il test verrà eseguito . Nota, stiamo usando il metodo di corrispondenza Hamcrest è (T) come matcher qui.

2.2. Utilizzando assumeTrue

Allo stesso modo, possiamo usare il metodo assumeTrue () per specificare un'espressione booleana che deve restituire true per l'esecuzione del test. Se restituisce false , il test verrà ignorato:

private boolean isExpectedOS(String osName) { return "Linux".equals(osName); } @Test public void whenAssumeTrueAndOSIsLinux_thenRunTest() { assumeTrue(isExpectedOS(getOsName())); assertEquals("run", "RUN".toLowerCase()); } 

In questo caso, isExpectedOs () restituisce true . Pertanto, le condizioni per l'esecuzione del test sono state soddisfatte e il test verrà eseguito .

2.3. Utilizzo di assumeFalse

Infine, possiamo utilizzare il metodo assumeFalse () opposto per specificare un'espressione booleana che deve restituire false affinché il test venga eseguito. Se restituisce true , il test verrà ignorato:

@Test public void whenAssumeFalseAndOSIsLinux_thenIgnore() { assumeFalse(isExpectedOS(getOsName())); assertEquals("run", "RUN".toLowerCase()); }

In questo caso, come isExpectedOs () anche restituisce vero, le condizioni per il test da eseguire non sono state rispettate, e il test verrà ignorato .

2.4. Utilizzando assumeNotNull

Quando vogliamo ignorare un test se qualche espressione è nulla, possiamo usare il metodo assumeNotNull () :

@Test public void whenAssumeNotNullAndNotNullOSVersion_thenRun() { assumeNotNull(getOsName()); assertEquals("run", "RUN".toLowerCase()); }

Poiché getOsName () restituisce un valore non nullo, la condizione per l'esecuzione del test è stata soddisfatta e il test verrà eseguito.

2.5. Utilizzo di assumeNoException

Infine, potremmo voler ignorare un test se viene generata un'eccezione. Possiamo usare assumeNoException () per questo scopo:

@Test public void whenAssumeNoExceptionAndExceptionThrown_thenIgnore() { assertEquals("everything ok", "EVERYTHING OK".toLowerCase()); String t=null; try { t.charAt(0); } catch(NullPointerException npe){ assumeNoException(npe); } assertEquals("run", "RUN".toLowerCase()); }

In questo esempio, come t è nullo, un NullPointerException viene generata un'eccezione, quindi le condizioni della prova di esecuzione non sono soddisfatti, e il test verrà ignorata .

3. Dove dovremmo mettere la chiamata assumeXXX ?

È importante notare che il comportamento dei metodi assumeXXX dipende da dove li inseriamo nei nostri test .

Modifichiamo leggermente il nostro esempio assumeThat in modo che la chiamata assertEquals () vada per prima. Inoltre, facciamo fallire assertEquals () :

@Test public void whenAssumeFalseAndOSIsLinux_thenIgnore() { assertEquals("run", "RUN"); assumeFalse(isExpectedOS(getOsName())); } 

Quando eseguiamo questo esempio, avremo:

org.junit.ComparisonFailure: Expected :run Actual :RUN

In questo caso, il nostro test non viene ignorato perché non è riuscito prima di raggiungere la chiamata assumeThat () . Lo stesso accade con tutti i metodi assumeXXX . Quindi, dobbiamo assicurarci di metterli nel posto giusto all'interno del nostro metodo di test .

4. Conclusione

In questo breve tutorial, abbiamo visto come possiamo decidere in modo condizionale se un test deve essere eseguito o meno, utilizzando la classe Assume in JUnit 4. Nel caso in cui stiamo usando JUnit 5, è disponibile anche nella versione 5.4 o successiva .

Come sempre, il codice sorgente degli esempi che abbiamo visto può essere trovato su GitHub.