繁体   English   中英

如何使用 junit5 平台启动器 api 从队列中发现测试?

[英]How do I use the junit5 platform launcher api to discover tests from a queue?

我希望将测试分发到 junit5 独立控制台的多个实例,每个实例都从队列中读取。 runner 的每个实例都会在类路径上使用相同的 test.jar,所以我不打算在这里分发实际测试的字节代码,只是测试/过滤器模式字符串的名称。

junit 5 高级主题文档,我认为扩展 junit 5 的适当位置是使用平台启动器 api。我将这段代码与指南中的示例代码拼凑在一起。 我认为这是我需要写的,但我担心我过于简化了这里涉及的工作:

// keep pulling test classes off the queue until its empty
while(myTestQueue.isNotEmpty()) {
    String classFromQueue = myTestQueue.next(); //returns "org.myorg.foo.fooTests"
    LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request()
        .selectors(selectClass(classFromQueue)).build();
        
    SummaryGeneratingListener listener = new SummaryGeneratingListener();
    try (LauncherSession session = LauncherFactory.openSession()) {
        Launcher launcher = session.getLauncher();
        launcher.registerTestExecutionListeners(listener);
        TestPlan testPlan = launcher.discover(request);
        launcher.execute(testPlan);
    }   
    TestExecutionSummary summary = listener.getSummary();
    addSummary(summary);
}

问题:

  1. 在 while 循环中反复发现和执行是否会违反正常的测试生命周期? 对于发现是否应该在所有处决之前发生的一次性事情,我有点模糊。
  2. 如果我假设可以重复发现然后执行,我发现 HierarchicalTestEngine 可能是从队列中读取的更好的地方,因为它似乎用于实现并行执行。 这更适合我的用例吗? 除了我可能不需要处理累积的测试摘要外,该实现是否与我上面的实现基本相同?

我不想采用的方法:我不想使用 junit 5 的新功能来在同一个 jvm 中并行执行测试。我也不想提前划分测试或类; 使用预先确定的测试子集启动每个控制台运行器实例。

简答

问题中发布的代码(松散地)说明了一种有效的方法。 无需创建自定义引擎。 利用平台启动器 api 反复发现和执行测试确实有效。 我认为值得强调的是您不必扩展 junit5 这不是通过您需要注册的扩展来执行的,就像我最初假设的那样。 您只是简单地利用平台启动器 api 来发现和执行测试。

长答案

下面是一些示例代码,其中包含一个简单的测试队列 class 名称,这些名称存在于 class 路径上。 当队列不为空时,testNode class 的实例将发现并执行三个测试类中的每一个,并编写 LegacyXmlReport。

测试节点代码:

package org.sample.node;
import org.junit.platform.launcher.Launcher;
import org.junit.platform.launcher.LauncherDiscoveryRequest;
import org.junit.platform.launcher.LauncherSession;
import org.junit.platform.launcher.TestPlan;
import org.junit.platform.launcher.core.LauncherConfig;
import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder;
import org.junit.platform.launcher.core.LauncherFactory;
import org.junit.platform.launcher.listeners.SummaryGeneratingListener;
import org.junit.platform.reporting.legacy.xml.LegacyXmlReportGeneratingListener;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.nio.file.Paths;
import java.util.LinkedList;
import java.util.Queue;

import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
public class TestNode {

    public void run() throws FileNotFoundException {

        // keep pulling test classes off the queue until its empty
        Queue<String> queue = getQueue();
        while(!queue.isEmpty()) {
            String testClass = queue.poll();
            LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request()
                    .selectors(selectClass(testClass)).build();


            LauncherConfig launcherConfig = LauncherConfig.builder()
                    .addTestExecutionListeners(new LegacyXmlReportGeneratingListener(Paths.get("target"), new PrintWriter(new FileOutputStream("log.txt"))))
                    .build();

            SummaryGeneratingListener listener = new SummaryGeneratingListener();
            try (LauncherSession session = LauncherFactory.openSession(launcherConfig)) {
                Launcher launcher = session.getLauncher();
                launcher.registerTestExecutionListeners(listener);
                TestPlan testPlan = launcher.discover(request);
                launcher.execute(testPlan);
            }
        }
    }

    private Queue<String> getQueue(){
        Queue<String> queue = new LinkedList<>();
        queue.add("org.sample.tests.Class1");
        queue.add("org.sample.tests.Class2");
        queue.add("org.sample.tests.Class3");
        return queue;
    }

    public static void main(String[] args) throws FileNotFoundException {
        TestNode node = new TestNode();
        node.run();
    }
}

TestNode 执行的测试

我只展示了三个测试类中的一个,因为它们都是相同的东西,但名称不同 class。 它们位于 src/main/java 而不是 src/test/java。 这是 maven 中用于将测试打包到胖 jar 中的一种公认的奇怪但常见的模式。

package org.sample.tests;

import org.junit.jupiter.api.Test;

public class Class1 {
    @Test
    void test1() {
        System.out.println("Class1 Test 1");
    }

    @Test
    void test2() {
        System.out.println("Class1 Test 2");
    }

    @Test
    void test3() {
        System.out.println("Class1 Test 3");
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM