Performance Zone is brought to you in partnership with:

I am the founder and CEO of Data Geekery GmbH, located in Zurich, Switzerland. With our company, we have been selling database products and services around Java and SQL since 2013. Ever since my Master's studies at EPFL in 2006, I have been fascinated by the interaction of Java and SQL. Most of this experience I have obtained in the Swiss E-Banking field through various variants (JDBC, Hibernate, mostly with Oracle). I am happy to share this knowledge at various conferences, JUGs, in-house presentations and on our blog. Lukas is a DZone MVB and is not an employee of DZone and has posted 220 posts at DZone. You can read more from them at their website. View Full User Profile

How to Execute Something Multiple Times in Java

02.28.2013
| 8136 views |
  • submit to reddit

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());
    }
}




Published at DZone with permission of Lukas Eder, author and DZone MVB. (source)

(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

Spock has a nice syntax for this problem:

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

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.