junitIniziare con junit


Osservazioni

JUnit è un semplice framework per scrivere test ripetibili per il linguaggio di programmazione Java . È un'istanza dell'architettura xUnit per i framework di test delle unità.

Le caratteristiche principali sono:

  • Asserzioni , che ti consentono di personalizzare come testare i valori nei tuoi test
  • Prova i corridori , che ti permettono di specificare come eseguire i test nella tua classe
  • Regole che ti consentono di modificare in modo flessibile il comportamento dei test nella tua classe
  • Suite , che ti permettono di costruire insieme una serie di test da molte classi diverse

Estensione utile per JUnit:

Versioni

Versione Data di rilascio
JUnit 5 Milestone 2 2016/07/23
JUnit 5 Milestone 1 2016/07/07
JUnit 4.12 2016/04/18
JUnit 4.11 2012/11/14
JUnit 4.10 2011-09-28
JUnit 4.9 2011-08-22
JUnit 4.8 2009-12-01
JUnit 4.7 2009-07-28
JUnit 4.6 2009-04-14

Installazione o configurazione

Poiché JUnit è una libreria Java, tutto ciò che devi fare per installarlo è aggiungere alcuni file JAR nel classpath del tuo progetto Java e sei pronto per partire.

È possibile scaricare manualmente questi due file JAR: junit.jar e hamcrest-core.jar .

Se stai usando Maven, puoi semplicemente aggiungere una dipendenza al tuo pom.xml :

<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.12</version>
  <scope>test</scope>
</dependency>
 

O se stai usando Gradle, aggiungi una dipendenza nel tuo build.gradle :

apply plugin: 'java'

dependencies {
    testCompile 'junit:junit:4.12'
}
 

Dopo questo puoi creare la tua prima classe di test:

import static org.junit.Assert.assertEquals;

import org.junit.Test;

public class MyTest {
    @Test
    public void onePlusOneShouldBeTwo() {
        int sum = 1 + 1;
        assertEquals(2, sum);
    }
}
 

ed eseguilo dalla riga di comando:

  • Windows java -cp .;junit-X.YY.jar;hamcrest-core-XYjar org.junit.runner.JUnitCore MyTest
  • Linux o OsX java -cp .:junit-X.YY.jar:hamcrest-core-XYjar org.junit.runner.JUnitCore MyTest

o con Maven: mvn test

@Prima dopo

Un metodo annotato con @Before verrà eseguito prima di ogni esecuzione dei metodi @Test . Analogamente un metodo @After annotato viene eseguito dopo ogni metodo @Test . Questo può essere usato per impostare ripetutamente un'impostazione di prova e pulire dopo ogni test. Quindi i test sono indipendenti e il codice di preparazione non viene copiato all'interno del metodo @Test .

Esempio:

import static org.junit.Assert.assertEquals;

import java.util.ArrayList;
import java.util.List;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class DemoTest {

    private List<Integer> list;

    @Before
    public void setUp() {
        list = new ArrayList<>();
        list.add(3);
        list.add(1);
        list.add(4);
        list.add(1);
        list.add(5);
        list.add(9);
    }

    @After
    public void tearDown() {
        list.clear();
    }

    @Test
    public void shouldBeOkToAlterTestData() {
        list.remove(0); // Remove first element of list.
        assertEquals(5, list.size()); // Size is down to five
    }

    @Test
    public void shouldBeIndependentOfOtherTests() {
        assertEquals(6, list.size());
    }
}
 

I metodi annotati con @Before o @After devono essere public void e con zero argomenti.

Esempio di test unitario di base

Questo esempio è una configurazione di base per l'unittesting di StringBuilder.toString () usando junit.

import static org.junit.Assert.assertEquals;

import org.junit.Test;

public class StringBuilderTest {

    @Test
    public void stringBuilderAppendShouldConcatinate()  {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("String");
        stringBuilder.append("Builder");
        stringBuilder.append("Test");

        assertEquals("StringBuilderTest", stringBuilder.toString());
    }

}
 

Catch previsto eccezione

È possibile catturare facilmente l'eccezione senza alcun blocco di try catch .

public class ListTest {
  private final List<Object> list = new ArrayList<>();

  @Test(expected = IndexOutOfBoundsException.class)
  public void testIndexOutOfBoundsException() {
    list.get(0);
  }
}
 

L'esempio precedente dovrebbe essere sufficiente per i casi più semplici, quando non si desidera / è necessario controllare il messaggio trasportato dall'eccezione generata.

Se si desidera verificare le informazioni sull'eccezione, si consiglia di utilizzare il blocco try / catch:

@Test
public void testIndexOutOfBoundsException() {
    try {
        list.get(0);
        Assert.fail("Should throw IndexOutOfBoundException");
    } catch (IndexOutOfBoundsException ex) {
        Assert.assertEquals("Index: 0, Size: 0", ex.getMessage());
    }
}
 

Per questo esempio è necessario essere consapevoli di aggiungere sempre Assert.fail() per garantire che il test fallisca quando non viene lanciata alcuna eccezione.

Per i casi più elaborati, JUnit ha la ExpectedException @Rule , che può testare anche queste informazioni e viene utilizzata come segue:

public class SimpleExpectedExceptionTest {
     @Rule
     public ExpectedException expectedException = ExpectedException.none();

     @Test
     public void throwsNothing() {
         // no exception expected, none thrown: passes.
     }

     @Test
     public void throwsExceptionWithSpecificType() {
         expectedException.expect(NullPointerException.class);

         throw new NullPointerException();
     }

     @Test
     public void throwsExceptionWithSpecificTypeAndMessage() {
         expectedException.expect(IllegalArgumentException.class);
         expectedException.expectMessage("Wanted a donut.");

         throw new IllegalArgumentException("Wanted a donut.");
     }
}
 

Test delle eccezioni in JUnit5

Per ottenere lo stesso risultato in JUnit 5, si utilizza un meccanismo completamente nuovo :

Il metodo testato

public class Calculator {
    public double divide(double a, double b) {
        if (b == 0.0) {
            throw new IllegalArgumentException("Divider must not be 0");
        }
        return a/b;
    }
}
 

Il metodo di prova

public class CalculatorTest {
    @Test
    void triangularMinus5() { // The test method does not have to be public in JUnit5
        Calculator calc = new Calculator();

        IllegalArgumentException thrown = assertThrows(
            IllegalArgumentException.class, 
            () -> calculator.divide(42.0, 0.0));
        // If the exception has not been thrown, the above test has failed.

        // And now you may further inspect the returned exception...
        // ...e.g. like this:
        assertEquals("Divider must not be 0", thrown.getMessage());
}
 

Test ignoranti

Per ignorare un test, è sufficiente aggiungere l'annotazione @Ignore al test e, facoltativamente, fornire un parametro all'annotazione con il motivo.

@Ignore("Calculator add not implemented yet.")
@Test
public void testPlus() {
    assertEquals(5, calculator.add(2,3));
}
 

Rispetto al commento del test o alla rimozione dell'annotazione @Test , il test runner riferirà comunque questo test e osserverà che è stato ignorato.

È anche possibile ignorare un caso di test in modo condizionale utilizzando le assunzioni di JUnit. Un caso d'uso esemplificativo sarebbe quello di eseguire il test-case solo dopo che un determinato bug è stato corretto da uno sviluppatore. Esempio:

import org.junit.Assume;
import org.junit.Assert;
...

@Test 
public void testForBug1234() {

    Assume.assumeTrue(isBugFixed(1234));//will not run this test until the bug 1234 is fixed

    Assert.assertEquals(5, calculator.add(2,3));
}
 

Il runner predefinito tratta i test con ipotesi errate come ignorate. È possibile che altri corridori possano comportarsi in modo diverso, ad esempio trattarli come superati.

JUnit: esempi di annotazioni di base

Ecco alcune annotazioni JUnit di base che dovresti capire:

@BeforeClass – Run once before any of the test methods in the class, public static void 
@AfterClass – Run once after all the tests in the class has been run, public static void
@Before – Run before @Test, public void
@After – Run after @Test, public void
@Test – This is the test method to run, public void