跳到主要内容
版本:4.0.2

测试 GraalVM Native Images

QWen Max 中英对照 Testing GraalVM Native Images

在编写原生镜像(native image)应用程序时,我们建议你尽可能继续使用 JVM 来开发大部分的单元测试和集成测试。这有助于缩短开发者的构建时间,并允许你使用现有的 IDE 集成。在 JVM 上拥有全面的测试覆盖后,你就可以将原生镜像测试集中在那些可能存在差异的区域。

对于 native image 测试,你通常需要确保以下方面能够正常工作:

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

  • GraalVM 拥有足够的提示信息,以确保可以生成有效的原生镜像。

使用 JVM 测试提前编译(Ahead-of-Time)处理​

当一个 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 配置文件。对于 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 可能是一个耗时的操作,因此大多数开发者可能更倾向于在本地使用 JVM。然而,它们在 CI 流水线中却非常有用。例如,你可以选择每天运行一次 native 测试。

Spring Framework 包含对运行测试的 ahead-of-time 支持。所有常用的 Spring 测试功能均可用于 native image 测试。例如,你可以继续使用 @SpringBootTest 注解。你也可以使用 Spring Boot test slices 来仅测试应用程序的特定部分。

Spring Framework 的原生测试支持以以下方式工作:

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

  • 对这些应用上下文逐一进行预先(Ahead-of-time)处理,并生成相关资源(assets)。

  • 创建一个原生镜像(native image),由 GraalVM 处理所生成的资源。

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

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

使用 Maven​

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

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

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

提示

如果你不想使用 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 构建文件中是否包含一个 plugins 块,并且其中包含 org.graalvm.buildtools.native。

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

$ gradle nativeTest