How to Execute Something Multiple Times in Java
When writing unit / integration tests, you often want to execute something multiple times, with different configurations / parameters / arguments every time. For instance, if you want to pass a “limit” or “timeout” or any other argument value of 1, 10, and 100, you could do this:
@Test
public void test() {
runCode(1);
runCode(10);
runCode(100);
}
private void runCode(int argument) {
// Run the actual test
assertNotNull(new MyObject(argument).execute());
}
Extracting methods is the most obvious approach, but it can quickly get nasty, as these extracted methods are hardly re-usable outside of that single test-case and thus don’t really deserve being put in their own methods. Instead, just use this little trick:
@Test
public void test() {
// Repeat the contents 3 times, for values 1, 10, 100
for (int argument : new int[] { 1, 10, 100 }) {
// Run the actual test
assertNotNull(new MyObject(argument).execute());
}
// Alternatively, use Arrays.asList(), which has a similar effect:
for (Integer argument : Arrays.asList(1, 10, 100)) {
// Run the actual test
assertNotNull(new MyObject(argument).execute());
}
}
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)






Comments
Tom VR replied on Thu, 2013/02/28 - 3:14am
Maybe you should take a look at the Parameterized Test of jUnit: http://junit.sourceforge.net/javadoc/org/junit/runners/Parameterized.html
Lukas Eder replied on Thu, 2013/02/28 - 3:52am
in response to:
Tom VR
Yes, I've heard this a couple of times as a reaction, recently ;-)
Parameterized can be useful, too. But there are scenarios where I'd like to keep it simple and just loop. E.g. outside of JUnit
Sam Lewis replied on Thu, 2013/02/28 - 8:07am
in response to:
Lukas Eder
def "test with spaces in the method name"() { when: def result = new MyObject(argument).execute() then: result != null where: argument << [1, 10, 100] }Jose Luis replied on Thu, 2013/02/28 - 8:40am
What about contiperf ?
Besides, you can also do performance testing.
import org.junit.*;
import org.databene.contiperf.*;
public class SmokeTest {
@Rule
public ContiPerfRule i = new ContiPerfRule();
@Test
@PerfTest(invocations = 1000, threads = 20)
@Required(max = 1200, average = 250)
public void test1() throws Exception {
Thread.sleep(200);
}
}
Jose Luis replied on Thu, 2013/02/28 - 8:40am
What about contiperf ?
Besides, you can also do performance testing.
import org.junit.*;
import org.databene.contiperf.*;
public class SmokeTest {
@Rule
public ContiPerfRule i = new ContiPerfRule();
@Test
@PerfTest(invocations = 1000, threads = 20)
public void test1() throws Exception {
Thread.sleep(200);
}
}
Oleg Ievtushok replied on Thu, 2013/03/14 - 4:02am
Here you posted an example with JUnit, but I would say that TestNG's DataProvider makes it more readable:
import static org.testng.Assert.assertNotEquals; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; public class DataProviderSample { @DataProvider(name = "data") public Object[][] createData() { return new Object[][] {{1}, {10}, {100}}; } //Data should be supplied by the Data Provider named "data" @Test(dataProvider = "data") public void test(Object parameter) { assertNotEquals(parameter, 0); } }The drawback of this approach is that you pass all your parameters as Objects, but instead you don't mix test logic with test data creation