【问题标题】:Running file-based tests on Junit 5 Platform using Apache Maven Surefire使用 Apache Maven Surefire 在 Junit 5 平台上运行基于文件的测试
【发布时间】:2020-10-10 17:28:38
【问题描述】:

我已经实现了一个自定义 TestEngine 类,它能够通过检查来自 Junit 5 的 EngineDiscoveryRequest 中的 FileSelector*.csv 文件(不是 java 类)中发现和运行单元测试。

我可以使用 Junit 团队提供的 ConsoleLauncher 通过调用 org.junit.platform.console.ConsoleLauncher -f build/resources/test/testfile_1.csv 毫无问题地运行这些测试(这是从 gradle 任务中调用的,因为 gradle does not support resource-based testing 但这在这里不重要)。

现在,我尝试使用相同的自定义测试引擎运行相同的测试,但使用 maven 和 surefire 插件而不是控制台启动器。我当前的pom.xml 如下(相关部分):

<project>
    <dependencies>
        <dependency>
            <groupId>my_custom_test_engine</groupId>
            <artifactId>custom_test_engine</artifactId>
            <version>1.0-SNAPSHOT</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.platform</groupId>
            <artifactId>junit-platform-engine</artifactId>
            <version>1.7.0-M1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.platform</groupId>
            <artifactId>junit-platform-console</artifactId>
            <version>1.7.0-M1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.7.30</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.0.0-M5</version>
            </plugin>
        </plugins>
    </build>
</project>

不幸的是,surefire:test 似乎甚至没有调用我的测试引擎进行发现,只是完成了:

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  0.626 s
[INFO] Finished at: 2020-06-20T17:00:01+02:00
[INFO] ------------------------------------------------------------------------

我的src 文件夹中没有任何测试类,resources/testfile_1.csv 下只有一个测试文件。

surefire 是否甚至支持使用 Junit 5 进行基于文件的测试?如果是这样,我如何强制 Surefire 调用我的自定义测试引擎进行测试发现?

-- 更新

我的TestEngine 实现的发现部分看起来像这样(仅显示相关部分):

public class MyTestEngine implements TestEngine {

    @Override
    public TestDescriptor discover(EngineDiscoveryRequest discoveryRequest, UniqueId uniqueId) {
        EngineDescriptor engineDescriptor = new EngineDescriptor(uniqueId, name);

        logger.debug("Discovering tests");

        discoveryRequest.getSelectorsByType(FileSelector.class).forEach(selector -> {
            logger.debug("Discovered: {}", selector.getFile().getAbsolutePath());
                engineDescriptor.addChild(new TestDescriptor (engineDescriptor.getUniqueId(), selector.getFile().getName()));

        });
}

-- 更新 2 我的测试文件位于src/test/resources

【问题讨论】:

  • 我没有看到对 junit-jupiter-api 的任何依赖?此外,surefire 通常负责查找测试用例,而这里不是这种情况。除此之外,TestEngine 是为 JUnit Jupiter 所知的测试引擎提供实现的接口。您是否使用@Testable 注释对您的部分进行了注释?您有项目的链接吗?
  • 嗯,这就是重点。我不想想要使用 Jupiter,因为我有自己的 TestEngine 实现。这个实现不依赖于测试类,而是依赖于测试文件(即csv文件),所以不能有任何@Testable注解。我用我的TestEngine 实现的相同示例代码更新了我的问题。
  • 不准确。您不想使用 junit-jupiter-engine 但您想使用 JUnit Jupiter 平台。此外,您至少需要使用 junit-jupiter-api 来触发surefire以加载正确的基础部件。除此之外,我不确定这是否会起作用,因为surefire依赖于识别你没有的类。此外,您在哪里找到了 csv 文件的问题?在src/test/resources?除此之外,我很好奇 CSV 文件相对于 Java 代码中真正的书面单元测试有什么优势?
  • 如果我错了,请纠正我,但是根据Junit用户指南,JUnit Jupiter是新编程模型和扩展模型的结合。我相当确定我不需要这些,因为我的TestEngine 在与ConsoleLauncher 一起运行时工作得非常好。控制台启动器在一个 gradle 项目中运行,我只依赖于 junit-platform-enginejunit-platform-console。关于用例: csv 文件将在运行时自动生成。它们不是传统意义上的“单元测试”,因为它们用于基于测试的代码搜索。
  • 我们在 Apache Maven 中已经意识到了这个问题,并在我们的计划中修复了这个问题。 Surefire 和 Failsafe 从未设计用于运行 CSV。不管你使用什么版本,插件总是使用类和方法运行。我们正在研究一个测试的抽象描述,它可以是任何东西,例如对于 JUnit5 以及运行文件等的唯一 ID。此功能需要进行重大更改才能重新处理插件的内部结构。顺便说一句,所有这些都在 SUREFIRE 的路线图中提到,请参阅首页:maven.apache.org/surefire/maven-surefire-plugin

标签: java maven junit junit5 maven-surefire-plugin


【解决方案1】:

想通了。感谢@johanneslink 为我指明了正确的方向。

Surefire 确实不支持基于资源的测试(另请参阅this issue)。 我所做的(正如@johanneslink 建议的那样)是创建一个空类,可以通过surefire 检测到,以便调用自定义TestEngine

public class TestInitializer {
}

然后,在我的TestEngine 中检查ClassSelector 并发现基于资源的测试:

discoveryRequest.getSelectorsByType(ClassSelector.class).forEach(selector -> {
            if (selector.getClassName().equals(TestInitializer.class.getName())) {
                discoverTests(new File(System.getenv("test_dir")), engineDescriptor);
            }
        });

我的测试文件所在的实际目录由环境变量test_dir指定。

那么,为了实际使用自定义TestEngine,修改你的pom.xml如下:

   <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.2</version>
                <configuration>
                    <dependenciesToScan>
                        <dependency>
                            my_custom_test_engine:custom_test_engine
                        </dependency>
                    </dependenciesToScan>
                    <includes>
                        <include>**/TestInitializer*
                        </include>
                    </includes>
                    <environmentVariables>
                        <test_dir>target/test-classes
                        </test_dir>
                    </environmentVariables>
                </configuration>
            </plugin>
        </plugins>
    </build>

dependenciesToScan 属性将确保,surefire 扫描包含 TestInitializer 类的依赖项。

请注意,maven-surefire-plugin 的最新版本 3.0.0-M5 在这方面似乎已被破坏,因为会发现并运行测试,但 Surefire 不会收到结果。请改用2.22.2

【讨论】:

  • @mlxyx 对不起,你错了。 Surefire 和 Failsafe 从未为 CSV 设计。不管你使用什么版本,插件总是使用类和方法运行。我们正在研究可以是任何东西的测试的抽象描述,例如与 JUnit5 以及运行文件一样的 UniqueID。此功能需要对插件的内部进行重大更改。顺便说一句,所有这些都在 SUREFIRE 的路线图中提到,请参阅带有路线图的首页:maven.apache.org/surefire/maven-surefire-plugin
  • @tibor17 请完整阅读答案。我的解决方法抽象出我正在测试 csv 文件的事实,这意味着 Surefire 仍然假设我正在测试类。这种方法确实适用于版本 2.22.2 但不适用于 3.0.0-M5,因此我的评论。另外:我在回答的开头确实说过 Surefire 不支持基于文件的测试。
猜你喜欢
  • 2020-12-31
  • 2018-09-02
  • 1970-01-01
  • 2020-07-25
  • 2019-09-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-14
相关资源
最近更新 更多