测试 GraalVM 原生镜像
在编写原生镜像应用程序时,我们建议您尽可能继续使用 JVM 来开发大部分单元和集成测试。这将有助于缩短开发构建时间,并允许您使用现有的 IDE 集成。通过在 JVM 上进行广泛的测试覆盖,您可以将原生镜像测试重点放在可能存在差异的区域。
对于原生镜像测试,您通常需要确保以下方面有效:
-
Spring AOT 引擎能够处理您的应用程序,并且它将以 AOT 处理模式运行。
-
GraalVM 有足够的提示以确保可以生成有效的原生镜像。
使用 JVM 测试提前 (Ahead-of-Time) 编译
当 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 Framework 包含用于运行测试的提前(Ahead-of-time,AOT)支持。所有常用的 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.3.5</version>
</parent>
spring-boot-starter-parent
声明一个nativeTest
配置文件,该配置文件配置运行原生测试所需的执行。您可以使用命令行上的-P
标志激活配置文件。
如果您不想使用spring-boot-starter-parent ,则需要为 Spring Boot 插件的process-test-aot 目标和原生构建工具插件的test 目标配置执行。 |
要构建镜像并运行测试,请使用test
目标并激活nativeTest
配置文件:
$ mvn -PnativeTest test