测试 GraalVM 原生镜像
在编写原生镜像应用程序时,我们建议您尽可能继续使用 JVM 来开发大部分的单元测试和集成测试。这将有助于减少开发者的构建时间,并使您能够利用现有的 IDE 集成。通过在 JVM 上实现广泛的测试覆盖,您可以专注于原生镜像测试中可能有所差异的部分。
对于原生镜像测试,您通常需要确保以下几个方面正常工作:
-
Spring AOT 引擎能够处理您的应用程序,并且它将以 AOT 处理的模式运行。
-
GraalVM 提供了足够的提示,以确保可以生成一个有效的原生镜像。
使用 JVM 测试提前处理
当一个 Spring Boot 应用运行时,它会尝试检测自己是否正在以原生镜像(native image)的方式运行。如果是,它将使用在构建时由 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 Native Build Tools)包含了在原生镜像中运行测试的能力。当你希望深入测试应用程序的内部在 GraalVM 原生镜像中的工作情况时,这一功能会非常有用。
生成包含要运行的测试的原生镜像可能是一项耗时的操作,因此大多数开发者可能更喜欢在本地使用 JVM。然而,它们作为 CI 管道的一部分可能非常有用。例如,您可以选择每天运行一次原生测试。
Spring Framework 包含了对运行测试的提前支持。所有常见的 Spring 测试功能都可以用于原生镜像测试。例如,你可以继续使用 @SpringBootTest 注解。你也可以使用 Spring Boot 的 测试切片 来仅测试应用程序的特定部分。
Spring Framework 的原生测试支持以如下方式工作:
-
测试被分析以发现任何将需要的 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.4.2</version>
</parent>
spring-boot-starter-parent
声明了一个 nativeTest
配置文件,该配置文件配置了运行原生测试所需的执行步骤。你可以使用命令行中的 -P
标志来激活这些配置文件。
如果你不想使用 spring-boot-starter-parent
,你需要为 Spring Boot 插件中的 process-test-aot
目标和 Native Build Tools 插件中的 test
目标配置执行。
要构建镜像并运行测试,请在激活 nativeTest
配置文件的情况下使用 test
目标:
$ mvn -PnativeTest test
使用 Gradle
当应用 GraalVM Native Image 插件时,Spring Boot Gradle 插件会自动配置 AOT 测试任务。你应该检查你的 Gradle 构建是否包含一个 plugins
块,其中包含 org.graalvm.buildtools.native
。
要使用 Gradle 运行原生测试,你可以使用 nativeTest
任务:
$ gradle nativeTest