测试 GraalVM Native Images
在编写 Native Image 应用时,我们建议尽可能继续使用 JVM 来开发绝大多数的单元测试和集成测试。这有助于减少开发人员的构建时间,并允许你使用现有的 IDE 集成。在 JVM 上进行广泛的测试覆盖后,你就可以将 Native Image 测试重点放在可能存在差异的领域。
对于 Native Image 测试,你通常需要确保以下方面正常工作:
-
Spring AOT 引擎能够处理你的应用,并且它将在 AOT 处理模式下运行。
-
GraalVM 拥有足够的提示信息来确保能够生成有效的 Native Image。
使用 JVM 测试提前编译处理 (AOT)
当一个 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 包含对运行测试的提前编译 (AOT) 支持。所有常规的 Spring 测试特性都适用于 Native Image 测试。例如,你可以继续使用 @SpringBootTest
注解。你还可以使用 Spring Boot 测试分片 来仅测试应用的特定部分。
Spring Framework 的 Native 测试支持工作方式如下:
-
对测试进行分析以发现所需的
ApplicationContext
实例。 -
对每个应用上下文应用提前编译处理 (AOT),并生成资源。
-
创建一个 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.4.5</version>
</parent>
spring-boot-starter-parent
声明了一个 nativeTest
profile,该 profile 配置了运行 Native 测试所需的执行。你可以使用命令行上的 -P
标志激活 profile。
如果你不想使用 spring-boot-starter-parent ,你需要为 Spring Boot 插件的 process-test-aot 目标和 Native Build Tools 插件的 test 目标配置执行。 |
要构建镜像并运行测试,请使用 test
目标并激活 nativeTest
profile
$ mvn -PnativeTest test