Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running two same tests with different arguments

I have a test with 15-20 different test cases, I want to run the same test with twice with two different parameters which are supposed to be passed to the test's BeforeClass method, for instance:

public class TestOne {
    private static ClassToTest classToTest;

    @BeforeClass
    public static void setUp() throws Exception {
        classToTest = new ClassToTest("Argument1", "Argument2");
    }

    @Test
    public void testOne() {
    ........roughly 15 - 20 tests here
}

public class TestTwo {
    private static ClassToTest classToTest;

    @BeforeClass
    public static void setUp() throws Exception {
        classToTest = new ClassToTest("Argument3", "Argument4");
    }

    @Test
    public void testOne() {
    ........roughly 15 - 20 tests here, same as in TestOne
}

As you can see the only difference between these two tests is in the setup method, which passes different values to the constructor of the ClassToTest. I don't want to replicate the test methods in both classes, but would prefer either inheritance or some other intelligent way to achieve this in one class.

like image 824
Ravi Avatar asked Mar 29 '12 16:03

Ravi


People also ask

Which annotation provide ability to run a test multiple times with different arguments?

Parameterized tests make it possible to run a test multiple times with different arguments. They are declared just like regular @Test methods but use the @ParameterizedTest annotation instead.

How do parameterized tests work?

Parameterized test is to execute the same test over and over again using different values. It helps developer to save time in executing same test which differs only in their inputs and expected results. Using Parameterized test, one can set up a test method that retrieves data from some data source.

How do you run the same test case multiple times in JUnit?

If you are implementing your own runner, then you could have the runner run the test 10 times. If you are using a third party runner, then with 4.7, you can use the new @Rule annotation and implement the MethodRule interface so that it takes the statement and executes it 10 times in a for loop.


3 Answers

This seems like a perfect use case for JUnit4's @Parameters; see https://blogs.oracle.com/jacobc/entry/parameterized_unit_tests_with_junit or http://www.mkyong.com/unittest/junit-4-tutorial-6-parameterized-test/ . That said, you'll have to move the initialization from the setUp method to a constructor for the test class.

like image 165
Louis Wasserman Avatar answered Sep 30 '22 19:09

Louis Wasserman


For what it's worth, here is how you would do it with TestNG:

public class TestFactory {
  @Factory
  public Object[] createTests() {
    return new Object[] {
      new ClassToTest("arg1", "arg2"),
      new ClassToTest("arg3", "arg4")
    };
  }
}

public class ClassToTest {
  public ClassToTest(String arg1, String arg2) {
    this.arg1 = arg1;
    this.arg2 = arg2;
  }

  @Test
  public void testOne() {
    // use arg1 and arg2
  }
}
like image 35
Cedric Beust Avatar answered Sep 30 '22 20:09

Cedric Beust


Thanks all for your quick replies. This is how I did it finally

public abstract class Base {
    final HeavyObject heavy;

    protected Base(HeavyObject heavy) {
        this.param = param;
    }

    @Test
    public void test() {
        param.doSomething();
    }

    @Test
    .............More tests here

}


public class FirstTest extends Base{

    private static HeavyObject param;

    @BeforeClass
    public static void init() {
        param = new HeavyObject("arg1", "arg2");
    }

    public FirstTest() {
        super(param);
    }
}

public class SecondTest extends Base{

    private static HeavyObject param;

    @BeforeClass
    public static void init() {
        param = new HeavyObject("arg3", "arg4");
    }

    public FirstTest() {
        super(param);
    }
}

Base is an abstract class which has all the tests and FirstTest and SecondTest create their own objects with different parameters and pass it to the abstract class to use it.

like image 41
Ravi Avatar answered Sep 30 '22 19:09

Ravi