首页 > 解决方案 > 外部库中定义的默认 JUnit5 测试

问题描述

对于很多项目,我们有多个类似的测试(有一些团队规则合规性架构测试),我希望有可能在库中创建一些测试并在其他项目中使用它。

此类测试的示例:测试代码中是否没有使用特定类。

这个库将被添加到项目类路径中,其中的测试将与项目特定的测试一起运行。

如何使用 JUnit 实现这一目标?

标签: javajunitjunit5

解决方案


两个选项:

选项 1:使用 JUnit (junit-platform-launcher)

考虑到 JUnit,你所追求的是

https://junit.org/junit5/docs/current/user-guide/#launcher-api

  1. 高级主题 6.1。JUnit 平台启动器 API

JUnit 5 的突出目标之一是使 JUnit 与其编程客户端(构建工具和 IDE)之间的接口更加强大和稳定。目的是将发现和执行测试的内部与外部所需的所有过滤和配置分离。

JUnit 5 引入了 Launcher 的概念,可用于发现、过滤和执行测试。此外,第三方测试库(如 Spock、Cucumber 和 FitNesse)可以通过提供自定义 TestEngine 插入到 JUnit 平台的启动基础设施中。

启动器 API 位于 junit-platform-launcher 模块中。

启动器 API 的一个示例使用者是 junit-platform-console 项目中的 ConsoleLauncher。6.1.1. 发现测试

将测试发现作为平台本身的一项专用功能,可以让 IDE 和构建工具摆脱他们必须经历的大部分困难,以识别以前版本的 JUnit 中的测试类和测试方法。

使用示例:

import static org.junit.platform.engine.discovery.ClassNameFilter.includeClassNamePatterns;
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectClass;
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectPackage;

import java.io.PrintWriter;
import java.nio.file.Path;
import java.nio.file.Paths;

import org.junit.platform.engine.FilterResult;
import org.junit.platform.engine.TestDescriptor;
import org.junit.platform.launcher.Launcher;
import org.junit.platform.launcher.LauncherDiscoveryListener;
import org.junit.platform.launcher.LauncherDiscoveryRequest;
import org.junit.platform.launcher.LauncherSession;
import org.junit.platform.launcher.LauncherSessionListener;
import org.junit.platform.launcher.PostDiscoveryFilter;
import org.junit.platform.launcher.TestExecutionListener;
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.launcher.listeners.TestExecutionSummary;
import org.junit.platform.reporting.legacy.xml.LegacyXmlReportGeneratingListener;

LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request()
    .selectors(
        selectPackage("com.example.mytests"),
        selectClass(MyTestClass.class)
    )
    .filters(
        includeClassNamePatterns(".*Tests")
    )
    .build();

try (LauncherSession session = LauncherFactory.openSession()) {
    TestPlan testPlan = session.getLauncher().discover(request);

    // ... discover additional test plans or execute tests
}

您可以选择包中的类、方法和所有类,甚至可以搜索类路径或模块路径中的所有测试。发现发生在所有参与的测试引擎中。

生成的 TestPlan 是适合 LauncherDiscoveryRequest 的所有引擎、类和测试方法的分层(和只读)描述。客户端可以遍历树,检索有关节点的详细信息,并获取到原始源的链接(如类、方法或文件位置)。测试计划中的每个节点都有一个唯一的 ID,可用于调用特定的测试或一组测试。

客户端可以通过 LauncherDiscoveryRequestBuilder 注册一个或多个 LauncherDiscoveryListener 实现,以深入了解测试发现期间发生的事件。默认情况下,构建器注册一个“失败时中止”侦听器,在遇到第一次发现失败后中止测试发现。可以通过 junit.platform.discovery.listener.default 配置参数更改默认 LauncherDiscoveryListener。

选项 2:使用 Maven

您的测试将需要属于他们自己的项目。

例子

<groupId>com.shared.projects</groupId>
<artifactId>common-tests</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>

然后从需要运行这些测试的任何其他项目中,添加依赖项:

    <dependency>
        <groupId>com.shared.projects</groupId>
        <artifactId>common-tests</artifactId>
        <version>1.0.0</version>
    </dependency>

然后使用 maven-surefire-plugin

 <project>
      [...]
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>3.0.0-M5</version>
            <configuration>
              <dependenciesToScan>
                <dependency>com.shared.projects:common-tests</dependency>
                <dependency>org.acme:project-b:test-jar</dependency>
                <dependency>org.acme:project-c:*:tests-jdk15</dependency>
              </dependenciesToScan>
            </configuration>
          </plugin>
        </plugins>
      </build>
      [...]
    </project>

Tests from dependencies

By default, Surefire will only scan for test classes to execute in the configured testSourceDirectory. To have the plugin scan dependencies to find test classes to execute, use the dependenciesToScan configuration. Dependencies can be specified using the groupId[:artifactId[:type[:classifier][:version]]] format, and must already be dependency elements in scope.

Note: Support for version, type and classifier was introduced in version 3.0.0-M4. When using earlier versions, Surefire will fail with an IllegalArgumentException if more than groupId and artifactId are specified.

<project>
  [...]
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>3.0.0-M5</version>
        <configuration>
          <dependenciesToScan>
            <dependency>org.acme:project-a</dependency>
            <dependency>org.acme:project-b:test-jar</dependency>
            <dependency>org.acme:project-c:*:tests-jdk15</dependency>
          </dependenciesToScan>
        </configuration>
      </plugin>
    </plugins>
  </build>
  [...]
</project>

上面的配置将在以下位置搜索测试类:

All dependencies with the groupId org.acme and artifactId project-a
All dependencies with the groupId org.acme and artifactId project-b and type test-jar
All dependencies with the groupId org.acme and artifactId project-c and classifier tests-jdk15

推荐阅读