While migrating some tests from JUnit to TestNG, I'm facing an issue because of the difference in how these test frameworks treat their Test class instances.
JUnit creates a new instance of the Test class for each test method. So a common pattern I see is:
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);
}
}
In contrast, TestNG uses a single instance of the Test class for all test methods. So the pattern above does not work! Because data is stored in instance fields, the values are no longer isolated. This can cause overwritten data mid-test if parallel execution is enabled.
So how would I do this with TestNG? Is there a way to store data which is isolated to each @BeforeMethod
-@Test
-@AfterMethod
tuple?
I can do all 3 steps inside the @Test
itself, but that would require adding ungainly try...finally
blocks to every test. I also tried using ITestContext
, but it also seems to be shared for the entire test run.
Yes, with TestNG you have way more power over those local variables that you did with JUnit AND the DataProvider handles your 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;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With