跳到主要内容
版本:3.5.10

测试 GraalVM Native Images

QWen Max 中英对照 Testing GraalVM Native Images

下面应使用英文内容翻译为中文内容:

你应该在 JVM 上编写大部分单元测试,而只针对那些在 Native Image 中可能表现不同的部分进行专门的 Native Image 测试。这有助于缩短开发者的构建时间,并允许你继续使用现有的 IDE 集成。在 JVM 上拥有全面的测试覆盖后,你就可以将 Native Image 测试集中在那些可能存在差异的区域。

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

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

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

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

当一个 Spring Boot 应用程序运行时,它会尝试检测自己是否作为原生镜像(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 中是否正常工作时,这会非常有帮助。

生成包含待运行测试的 native image 可能是一个耗时的操作,因此大多数开发者可能更倾向于在本地使用 JVM。然而,它们在 CI 流水线中却非常有用。例如,你可以选择每天运行一次 native 测试。

Spring Framework 包含对运行测试的 ahead-of-time(AOT)支持。所有常用的 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>3.5.10</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