测试 GraalVM Native Images

在编写 native image 应用程序时,我们建议您尽可能继续使用 JVM 来开发大部分单元测试和集成测试。 这将有助于减少开发者的构建时间,并允许您使用现有的 IDE 集成。 通过 JVM 上的广泛测试覆盖,您可以专注于可能在 native image 中表现不同的领域进行测试。

对于 native image 测试,您通常需要确保以下几个方面正常工作:

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

  • GraalVM 有足够的提示来确保可以生成有效的 native image。

使用 JVM 测试提前编译处理

当 Spring Boot 应用程序运行时,它会尝试检测是否作为 native image 运行。 如果是作为 native image 运行,它将使用 Spring AOT 引擎在构建时生成的代码来初始化应用程序。

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

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

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

例如:

$ java -Dspring.aot.enabled=true -jar myapplication.jar

注意:您需要确保您测试的 jar 包含 AOT 生成的代码。 对于 Maven,这意味着您应该使用 -Pnative 来激活 native profile。 对于 Gradle,您需要确保您的构建包含 org.graalvm.buildtools.native 插件。

如果您的应用程序在设置 spring.aot.enabled 属性为 true 的情况下启动,那么您对它在转换为 native image 时能够正常工作会有更高的信心。

您还可以考虑对运行中的应用程序运行集成测试。 例如,您可以使用 Spring WebClient 来调用您的应用程序 REST 端点。 或者您可能考虑使用像 Selenium 这样的项目来检查您的应用程序的 HTML 响应。

使用 Native Build Tools 进行测试

GraalVM Native Build Tools 包含在 native image 中运行测试的功能。 当您想要深入测试应用程序内部在 GraalVM native image 中的工作情况时,这可能会很有帮助。

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

Spring Framework 包含用于运行测试的提前编译支持。 所有常用的 Spring 测试功能都可以与 native image 测试一起使用。 例如,您可以继续使用 @SpringBootTest 注解。 您还可以使用 Spring Boot 测试切片 来仅测试应用程序的特定部分。

Spring Framework 的 native 测试支持按以下方式工作:

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

  • 对每个应用程序上下文应用提前编译处理并生成资源。

  • 创建 native image,生成的资源由 GraalVM 处理。

  • native image 还包括配置了已发现测试列表的 JUnit TestEngine

  • 启动 native image,触发引擎运行每个测试并报告结果。

使用 Maven

要使用 Maven 运行 native 测试,请确保您的 pom.xml 文件使用 spring-boot-starter-parent。 您应该有一个如下所示的 <parent> 部分:

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

spring-boot-starter-parent 定义了一个 nativeTest profile,为 Spring Boot 和 Native Build Tools 插件提供必要的配置。 首先,您需要在模块中添加这两个插件以选择使用该功能。 只有在启用 nativeTest 时,您的测试才会在 native 模式下执行。 您可以使用命令行上的 -P 标志来激活 profiles。

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

要构建镜像并运行测试,请使用 test 目标并激活 nativeTest profile:

$ mvn -PnativeTest test

使用 Gradle

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

要使用 Gradle 运行 native 测试,您可以使用 nativeTest 任务:

$ gradle nativeTest