0

What's the easiest way of injecting a set of parameters to a @Parameterized test class?

Use case:

I have a regular class that looks like this

@RunWith(Parameterized.class)
class Tests {

    public void testOne() { }
    public void testTwo() { }

    @Parameters
    public static Collection<Object[]> generateData() { }

}

A standard JUnit runner can be invoked like this: org.junit.runner.JUnitCore.runClasses(TestClass1.class, ...);

however, there is no way of then specifying/overriding the parameters.

How can I inject my own parameters?

Christian Neverdal
  • 5,655
  • 6
  • 38
  • 93
  • This seems like [an XY problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). Is it fair to say your underlying question is: **How can I easily run only the tests that failed out of a large parameterized test?** If so, can you confirm which IDE you are using, assuming you are trying to achieve this goal within an IDE? – Duncan Jones Feb 11 '15 at 08:01
  • It is fair to say that my underlying question is: *While it is possible to run test class using (for example) JUnitCore, how can I also pass along parameters so that it will not use the parameters given in @Parameters.*? – Christian Neverdal Feb 11 '15 at 12:21
  • Could you please provide more information about the meaning of "inject my own parameters". – Stefan Birkner Apr 15 '15 at 18:08
  • Let's say I now want to have a class that will run a test from this test class but with a given Object[] that I specify. – Christian Neverdal Apr 16 '15 at 12:33

2 Answers2

0

junit is not designed for running someone else's junit class with your parameters. so if possible, refactor you test classes to make them support your desired behavior. if you can't refactor then all you can do is to use some workarounds. for example:

  • if test class is written 'correctly' (e.g. no static references) then you can inherit from the test class and provide your own parameters. but still you have to provide parameters explicitly in class file, not during run
  • you can try to use custom class loader and bytecode generation/transformation to change the parameter provider method on class load. same way as PowerMockito works
  • write you custom runner so it will ignore in-class parameters and use your own instead
piotrek
  • 13,982
  • 13
  • 79
  • 165
-1

I would use a generateData() method which generates all five hundred elements. In addition, I would add a method getParameters() annotated with @Parameters. It could invoke generateData() to get the full collection, then load the log file (if present) and reduce the collection to the failing test parameters. If no log file is present, it will return the whole collection. You might need to explicitly name your parameters to be able to identify them because JUnit is not guaranteed to re-run the tests / test parameters in the same order (see Changing names of parameterized tests).

@RunWith(Parameterized.class)
public class Tests {

  @Parameters
  public static Collection<Object[]> getParameters() {
    List<Object[]> parameters = generateData();
    return filterParameters(parameters);
  }

  private static Collection<Object[]> filterParameters(Collection<Object[]> params) {
    // load a file to exclude successful tests
    // ...
  }

  private static Collection<Object[]> generateData() {
    return new ArrayList<Object[]>();
  }
}

Another way might be to use a Scanner with System.in in the @Parameters method so that you can select the parameters with user input from the console. However, you will need to ensure somehow that the tests can still be run without user interaction if you want to use them in continuous integration.

Community
  • 1
  • 1
nrainer
  • 2,542
  • 2
  • 23
  • 35