簡體   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