测试 GraalVM Native Images

在编写原生镜像应用程序时,我们建议您尽可能继续使用 JVM 来开发大多数单元测试和集成测试。这将有助于缩短开发人员的构建时间,并允许您使用现有的 IDE 集成。通过在 JVM 上进行广泛的测试覆盖,您可以将原生镜像测试重点放在可能有所不同的领域。

对于原生镜像测试,您通常需要确保以下方面正常工作

  • Spring AOT 引擎能够处理您的应用程序,并且它将在 AOT 处理模式下运行。

  • GraalVM 有足够的提示来确保可以生成有效的原生镜像。

使用 JVM 测试提前编译处理

当 Spring Boot 应用程序运行时,它会尝试检测它是否以原生镜像的形式运行。如果它以原生镜像的形式运行,它将使用在构建时由 Spring AOT 引擎生成的代码来初始化应用程序。

如果应用程序在常规 JVM 上运行,则会忽略任何 AOT 生成的代码。

由于 native-image 编译阶段可能需要一段时间才能完成,因此有时在 JVM 上运行您的应用程序但让它使用 AOT 生成的初始化代码会很有用。这样做有助于您快速验证 AOT 生成的代码中没有错误,并且在您的应用程序最终转换为原生镜像时不会丢失任何内容。

要在 JVM 上运行 Spring Boot 应用程序并让它使用 AOT 生成的代码,您可以将 spring.aot.enabled 系统属性设置为 true

例如

$ java -Dspring.aot.enabled=true -jar myapplication.jar
您需要确保您正在测试的 jar 包含 AOT 生成的代码。对于 Maven,这意味着您应该使用 -Pnative 构建以激活 native 配置文件。对于 Gradle,您需要确保您的构建包含 org.graalvm.buildtools.native 插件。

如果您的应用程序以 spring.aot.enabled 属性设置为 true 的方式启动,那么您更有信心它在转换为原生镜像时可以正常工作。

您还可以考虑对正在运行的应用程序运行集成测试。例如,您可以使用 Spring WebClient 来调用您的应用程序 REST 端点。或者,您也可以考虑使用 Selenium 之类的项目来检查您的应用程序的 HTML 响应。

使用原生构建工具进行测试

GraalVM 原生构建工具包括在原生镜像中运行测试的能力。当您想深入测试应用程序的内部机制在 GraalVM 原生镜像中是否正常工作时,这会很有帮助。

生成包含要运行的测试的原生镜像可能是一个耗时的操作,因此大多数开发人员可能更愿意在本地使用 JVM。但是,它们作为 CI 管道的一部分非常有用。例如,您可能选择每天运行一次原生测试。

Spring 框架包含用于运行测试的提前编译支持。所有常见的 Spring 测试功能都适用于原生镜像测试。例如,您可以继续使用 @SpringBootTest 注解。您还可以使用 Spring Boot 测试切片 来仅测试应用程序的特定部分。

Spring 框架的原生测试支持以以下方式工作

  • 分析测试以发现将需要的任何 ApplicationContext 实例。

  • 将提前编译处理应用于每个应用程序上下文,并生成资产。

  • 创建原生镜像,并由 GraalVM 处理生成的资产。

  • 原生镜像还包括配置了已发现测试列表的 JUnit TestEngine

  • 启动原生镜像,触发引擎,该引擎将运行每个测试并报告结果。

使用 Maven

要使用 Maven 运行原生测试,请确保您的 pom.xml 文件使用 spring-boot-starter-parent。您应该有一个类似于以下内容的 <parent> 部分

<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>3.3.0</version>
</parent>

spring-boot-starter-parent 声明了一个 nativeTest 配置文件,该配置文件配置运行原生测试所需的执行。您可以使用命令行上的 -P 标志激活配置文件。

如果您不想使用 spring-boot-starter-parent,则需要为 Spring Boot 插件的 process-test-aot 目标和 Native Build Tools 插件的 test 目标配置执行。

要构建镜像并运行测试,请使用 test 目标,并激活 nativeTest 配置文件

$ mvn -PnativeTest test

使用 Gradle

当应用 GraalVM Native Image 插件时,Spring Boot Gradle 插件会自动配置 AOT 测试任务。您应该检查您的 Gradle 构建是否包含一个包含 org.graalvm.buildtools.nativeplugins 块。

要使用 Gradle 运行原生测试,您可以使用 nativeTest 任务

$ gradle nativeTest