Question

I want to reuse some integration tests for load testing purposes. I implemented a rule which is parameterized by an annotation:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Parallel {

    int invocations() default 1;

    int rampUpTime() default 0;
}

In my rule implementation the annotation is evaluated and a statement is set up, which has a evaluate method like that:

@Override
public void evaluate() throws Throwable {
    ScheduledExecutorService exe = Executors.newScheduledThreadPool(invocations);

    for (int i = 0; i < invocations; i++) {
        ScheduledFuture<?> scheduledFuture = exe.schedule(new Runnable() {

            @Override
            public void run() {
                try {
                    invocated++;

                    // Request test = Request.method(description.getTestClass(), description.getMethodName());
                    // new JUnitCore().run(test);

                    statement.evaluate();
                } catch (Throwable e) {
                    e.printStackTrace();
                }
            }
        }, i * rampUpTime, this.timeUnit);
        futures.add(scheduledFuture);
    }
}

So, the evaluate call gets wrapped in a Runnable() and scheduled as described in the annotation. The thing is: In my rule, only the scheduling takes place, the runner doesn´t know (or care) about all the runables which only run as long as it takes to set up the whole test suite. So I´m trying to add the calls to evalute() to the test runner. First try was to use JUnitCore.run(...) which of course ends in a recursion.

Next try was to collect all the futures and wait for them to finish. This works fine on a per test basis, but I want to execute a whole test suite in parallel. And also, in my test report, I only see the test being executed once.

So then I thought I use a parameterized suite with a context (an object which collects all the futures from all tests) as parameter, but I didn´t found a way to promote this context object to the tests, each test has to have its own parameters.

I´m now asking for a way to add multiple executions from my rule to the test runner which is executing it.

Was it helpful?

Solution

If I'm understanding you correctly, you are trying to control the execution behaviour of the test runner. A TestRule might be to limited to achieve that goal. But how about writing your own Runner which controls the execution flow of your unit test? Just have a look at the ParentRunner of JUnit. From there, you should get a pretty good idea how the basic scheduling works, and maybe implement your own version of org.junit.experimental.ParallelComputer.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top