9

I was annoyed to find in the Parameterized documentation that "when running a parameterized test class, instances are created for the cross-product of the test methods and the test data elements." This means that the constructor is run once for every single test, instead of before running all of the tests. I have an expensive operation (1-5 seconds) that I put in the constructor, and now the operation is repeated way too many times, slowing the whole test suite needlessly. The operation is only needed once to set the state for all of the tests. How can I run several tests with one instance of a parameterized test?

1
  • tests should be run in isolation. if you can, follow Duncan Jones' suggestion. Commented Jan 21, 2013 at 16:31

1 Answer 1

9

I would move the expensive operation to a @BeforeClass method, which should execute just once for the entire parameterized test.

A silly example is shown below:

@RunWith(Parameterized.class)
public class QuickTest {

  private static Object expensiveObject;  
  private final int value;

  @BeforeClass
  public static void before() {
    System.out.println("Before class!");
    expensiveObject = new String("Just joking!");
  }


  @Parameters
  public static Collection<Object[]> data() {
    return Arrays.asList(new Object[][] { { 1 }, { 2 } });
  }      

  public QuickTest(int value) {
    this.value = value;
  }

  @Test
  public void test() {
    System.out.println(String.format("Ran test #%d.", value));
    System.out.println(expensiveObject);
  }
}

Will print:

Before class!
Ran test #1.
Just joking!
Ran test #2.
Just joking!
Sign up to request clarification or add additional context in comments.

8 Comments

Ah! Thanks. I was using Before and AfterClass as if they would run before and after the first and last parameterized tests. Is there a way to do that (static block for before, and something else for after...)?
Not sure I understand what you want. @BeforeClass and @AfterClass would allow you to set-up and tear-down your test data. Both need to be public static void methods.
Yes, that's exactly what I asked for in my question. I was just wondering, because I was using BeforeClass and AfterClass incorrectly, if there's a way to run stuff before starting any of the tests and after finishing all of the tests.
I'm very confused now! To run stuff before starting any tests, use @BeforeClass. To run stuff after all the tests, use @AfterClass. There are no other options that I know of! What functionality are you looking for that isn't provided by @BeforeClass and @AfterClass?
@BeforeClass and @AfterClass are run before and after each parameterized test. So, with 5 parameter elements they would each run 5 times. I'm asking for something that would be run by JUnit before and after running all of the parameterized tests. So even with 5 parameter elements they would only be run once.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.