2013-10-05 1 views
24

Attualmente sto facendo il mio primo progetto Java e mi piace completamente TDD esso. Sto usando JUnit per scrivere i test. Apparentemente JUnit non fornisce supporto per data providers, il che rende piuttosto noioso testare lo stesso metodo con 20 diverse versioni di un argomento. Qual è lo strumento di test più diffuso/standard per Java che supporta i fornitori di dati? Mi sono imbattuto nello TestNG, ma non ho idea di quanto sia popolare, o di come sia paragonabile alle alternative.Scrittura di test Java con provider di dati

Se c'è un modo per ottenere questo comportamento è un modo carino con JUnit, quindi potrebbe funzionare anche.

+0

JUnit ha test parametrizzati. –

+0

Ma attenzione, l'integrazione di Eclipse per il test JUnit parametrizzato fa schifo. a) Non è possibile eseguire un singolo set di parametri, b) è difficile da distinguere dalla finestra di JUnit, quale parametro ha effettivamente fallito durante il test (si vedono qualcosa come [0], [1], [2] nell'elenco). – qqilihq

+2

@qqilihq JUnit 4.11 ora ha modi per nominare meglio i test parametrizzati in modo da non avere più questo tipo di problema https://github.com/junit-team/junit/blob/master/doc/ReleaseNotes4.11.md – dkatzel

risposta

23

JUnit 4 è parametrizzato test che è lo fa la stessa cosa di fornitori di dati php

@RunWith(Parameterized.class) 
public class MyTest{ 
    @Parameters 
    public static Collection<Object[]> data() { 
      /*create and return a Collection 
      of Objects arrays here. 
      Each element in each array is 
      a parameter to your constructor. 
      */ 

    } 

    private int a,b,c; 


    public MyTest(int a, int b, int c) { 
      this.a= a; 
      this.b = b; 
      this.c = c; 
    } 

    @Test 
    public void test() { 
      //do your test with a,b 
    } 

    @Test 
    public void testC(){ 
     //you can have multiple tests 
     //which all will run 

     //...test c 
    } 
} 
+4

Questo è simile, anche se non è lo stesso. I fornitori di dati PHP passano argomenti ai tuoi metodi. Nel tuo esempio, gli argomenti vengono passati al costruttore della classe di test. Cosa succede se ho più metodi di test per i quali voglio avere una lista di valori? Creare una classe di test per ciascuno sarebbe molto imbarazzante. –

+0

È possibile avere più metodi di test annotati ciascuno con un '@ Test'. Tutti i test saranno esercitati. Ho aggiornato leggermente la mia risposta per mostrare come – dkatzel

+8

è utile quando si hanno più test che utilizzano lo stesso elenco di argomenti o elementi della stessa lista. Se non c'è sovrapposizione, non è di grande aiuto. Nel mio caso ho un elenco di input validi e un elenco di input non validi, per i quali non esiste alcuna sovrapposizione. Metterli insieme sarebbe estremamente strano. –

6

a seconda delle esigenze in termini di flessibilità vs leggibilità, è possibile scegliere Parameterized - JUnit è costruito in opzione, descritta da dkatzel. Altre opzioni sono corridori JUnit esterni forniti da librerie esterne come zohhak, che ti permette di fate:

@TestWith({ 
     "clerk,  45'000 USD, GOLD", 
     "supervisor, 60'000 GBP, PLATINUM" 
    }) 
    public void canAcceptDebit(Employee employee, Money money, ClientType clientType) { 
     assertTrue( employee.canAcceptDebit(money, clientType) ); 
    } 

o junitParams con una funzionalità po 'diverso. scegli quello che più ti si addice

36

I miei colleghi della nostra azienda hanno scritto un DataProvider disponibile gratuitamente in TestNG per JUnit che puoi trovare on github (https://github.com/TNG/junit-dataprovider).

Lo usiamo in progetti molto grandi e funziona perfettamente per noi. Ha alcuni vantaggi rispetto a Parameterized di JUnit in quanto ridurrà il sovraccarico di classi separate ed è possibile eseguire anche singoli test.

Un esempio sembra qualcosa di simile

@DataProvider 
public static Object[][] provideStringAndExpectedLength() { 
    return new Object[][] { 
     { "Hello World", 11 }, 
     { "Foo", 3 } 
    }; 
} 

@Test 
@UseDataProvider("provideStringAndExpectedLength") 
public void testCalculateLength(String input, int expectedLength) { 
    assertThat(calculateLength(input)).isEqualTo(expectedLength); 
} 

Edit: Dal v1.7, supporta anche altri modi per fornire dati (stringhe, liste) e può InLine il provider in modo che un metodo separato è non necessariamente necessario.

Un esempio completo e funzionante è disponibile nella pagina di manuale su github. Ha anche alcune funzionalità in più, come la raccolta dei provider nelle classi di utilità e l'accesso ad esse da altre classi, ecc. La pagina di manuale è molto dettagliata, sono sicuro che troverai qualsiasi risposta alle tue domande.

+2

Per quelli di voi che cercano di eseguire l'esempio sopra: non dimenticate di aggiungere l'annotazione '@RunWith (DataProviderRunner.class)' alla vostra classe di test! – ADi3ek