在@Rule中并行化测试执行



我想重用一些集成测试来进行负载测试。我实现了一个由注释参数化的规则:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Parallel {
    int invocations() default 1;
    int rampUpTime() default 0;
}

在我的规则实现中,对注释进行评估,并设置一个语句,该语句具有如下评估方法:

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

因此,evaluate调用被封装在Runnable()中,并按照注释中的描述进行调度。问题是:在我的规则中,只进行调度,运行者不知道(或关心)所有的可运行程序,这些可运行程序只在设置整个测试套件时运行。因此,我尝试将对evalute()的调用添加到测试运行程序中。第一次尝试是使用JUnitCore.run(...),它当然以递归结束。

下一个尝试是收集所有的期货并等待它们完成。这在每次测试的基础上运行良好,但我想并行执行整个测试套件。而且,在我的测试报告中,我只看到测试执行了一次。

所以我想我使用一个带有上下文(一个从所有测试中收集所有未来的对象)作为参数的参数化套件,但我没有找到将这个上下文对象提升到测试中的方法,每个测试都必须有自己的参数。

我现在正在寻求一种方法,将我的规则中的多个执行添加到正在执行它的测试运行程序中。

如果我理解正确,那么您正在尝试控制测试运行程序的执行行为。TestRule可能被限制以实现该目标。但是,编写自己的Runner来控制单元测试的执行流程怎么样?只要看看JUnit的ParentRunner。从那里,您应该对基本调度的工作原理有一个很好的了解,也许还可以实现自己版本的org.junit.experimental.ParallelComputer

最新更新