2015-09-12 24 views
5

Durante la migrazione di alcuni test da JUnit a TestNG, sto affrontando un problema a causa della differenza nel modo in cui questi framework di test trattano le istanze della classe Test.Inizializza e pulisce i dati per test per test paralleli in TestNG

JUnit crea una nuova istanza della classe Test per ciascun metodo di prova. Quindi, un modello comune che vedo è:

public class MyTest { 

    private Stream inputData; 

    @Before 
    public void setUp() { 
     // Set up some data in (non-static) instance fields 
     // This data is isolated per test 
     inputData = createInputDataStream(); 
    } 

    @Test 
    public void testStuff() { 
     // Use the data from the instance fields 
     doStuff(inputData); 
    } 

    @After 
    public void tearDown() { 
     // Clean up the data from the instance fields 
     closeInputDataStream(inputData); 
    } 
} 

Al contrario, TestNG usa una singola istanza della classe di prova per tutti i metodi di prova. Quindi il modello sopra non funziona! Poiché i dati sono memorizzati nei campi di istanza, i valori non sono più isolati. Ciò può causare un mid-test dei dati sovrascritti se l'esecuzione parallela è abilitata.

Quindi come farei con TestNG? Esiste un modo per archiviare dati isolati per ciascuna tupla @BeforeMethod - @Test - @AfterMethod?

È possibile eseguire tutti e 3 i passaggi all'interno dello stesso @Test, ma ciò richiederebbe l'aggiunta di blocchi try...finally sgraziati a ogni test. Ho anche provato a utilizzare ITestContext, ma sembra anche essere condiviso per l'intera esecuzione del test.

+1

'@ BeforeMethod' e' @AfterMethod 'viene chiamato in giro per ogni invocazione' @ Test'; quindi questo dovrebbe funzionare esattamente come hai descritto. L'unica differenza è che puoi ignorare lo stato della classe ogni volta, piuttosto che creare una nuova istanza. Hai notato un comportamento inaspettato con tale approccio? O stai cercando di eseguire tutti i test della classe in parallelo (temo che non sia possibile)? –

+0

@CostiCiudatu Principalmente durante l'esecuzione parallela: a volte i valori vengono sovrascritti a metà test. – metacubed

+0

Se vuoi eseguire i metodi di test all'interno della classe in parallelo (''), non c'è modo di difendersi dalle condizioni di gara, dal momento che stai modificando lo stato mutabile. –

risposta

1

Sì, con TestNG avete modo più potere su quelle variabili locali che hai fatto con JUnit E DataProvider gestisce il threading, per test-class-instance:

public class MyTest { 

private Stream inputData; 

@BeforeMethod 
public void setUp(Object[] args) { 
    inputData = (Data)args[0]; 
    inputData = normalizeDataBeforeTest(inputData); 
} 

@Test(dataProvider="testArgs") 
public void testStuff(Data inputDatax, Object a, Object b) { 
    doSomethingWith(a); 
    doSomethingWith(b); 
    doStuff(this.inputData); 
} 

@AfterMethod 
public void tearDown() { 
    // Clean up the data from the instance fields 
    closeInputDataStream(inputData); 
} 

.... 
@DataProvider 
public static Object[][] testArgs() { 
    // generate data here, 1 row per test thread 
    Object[][] testData; 
    for loop { 
     // add row of data to testData 
     // {{dataItem, obja, objb}, {dataItem, obja, objb}} etc. 
    } 
    return testData; 
} 
}