此页面介绍了 Kotlin 的代码生成测试,这是编译器测试基础设施的关键部分。代码生成测试会验证 Kotlin 源代码是否已正确编译为目标平台(JVM、JS、Native、WebAssembly),以及生成的代码在运行时是否按预期运行。
有关验证编译器错误和警告的诊断测试信息,请参阅诊断测试。
Kotlin 中的代码生成测试采用“黑盒”方法,侧重于验证已编译代码的行为,而不是检查其内部结构。这些测试会编译 Kotlin 代码,在目标平台上执行,并验证结果是否符合预期。
黑盒方法有几个优点:
代码生成测试框架围绕几个关键组件构建:
来源:compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsCodegenBoxTestGenerated.java native/native.tests/tests-gen/org/jetbrains/kotlin/konan/test/blackbox/FirNativeCodegenBoxTestGenerated.java wasm/wasm.tests/tests-gen/org/jetbrains/kotlin/wasm/test/FirWasmJsCodegenBoxTestGenerated.java
测试代码遵循一个约定:每个测试文件必须包含一个作为入口点的 box() 函数。如果 box() 函数返回字符串 "OK",则认为测试成功。
测试按以下方式分层组织:
来源:compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java29-985 compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsCodegenBoxTestGenerated.java native/native.tests/tests-gen/org/jetbrains/kotlin/konan/test/blackbox/FirNativeCodegenBoxTestGenerated.java wasm/wasm.tests/tests-gen/org/jetbrains/kotlin/wasm/test/FirWasmJsCodegenBoxTestGenerated.java
测试执行过程遵循以下步骤:
来源:compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java20-26 compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/inlineScopes/FirBlackBoxCodegenTestWithInlineScopesGenerated.java26-27
黑盒测试在以下不同组合下运行:
来源:compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/inlineScopes/FirBlackBoxCodegenTestWithInlineScopesGenerated.java compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenWithIrInlinerTestGenerated.java compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/JvmAbiConsistencyTestBoxGenerated.java
测试类是通过测试数据目录使用测试生成器自动生成的。每个测试类对应一个特定的前端/后端组合,嵌套类代表功能区域,测试方法代表各个测试用例。
例如,使用 FIR 和 PSI 的 JVM 平台上的注解测试生成为:
来源:compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java19-20 compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java29-45
测试套件涵盖了全面的语言功能和边缘情况,包括:
| 类别 | 描述 | 示例测试文件 |
|---|---|---|
| Annotations | 注解处理测试 | annotationsOnTypeAliases.kt, annotationProperty.kt |
| Argument Order | 函数参数求值顺序测试 | argumentOrderInSuperCall.kt, capturedInExtension.kt |
| 算术 | 数值运算测试 | basic_charConversions.kt, divisionByZero.kt |
| 数组 | 数组处理测试 | arrayConstructor.kt, arrayLiterals.kt |
| Casting | 类型转换操作测试 | implicitCastToUnit.kt, safeCastSureToBe.kt |
| 类 | 类声明和使用测试 | abstractMethodInFakeOverride.kt, compactConstructor.kt |
| 合集 | 集合操作测试 | forInArrayWithIndex.kt, mapGetWithDefaultWithNullableValues.kt |
| 控制流 | 分支和循环测试 | breakContinueInLoopWithLabel.kt, whenByDelegated.kt |
| Delegated Properties | 属性委托测试 | delegateToNestedInlineFunction.kt, delegationsByMap.kt |
| 泛型 | 泛型测试 | boundedTypeParameterUpperChecker.kt, invariantArraysOfGenericCompare.kt |
| 内联 | 内联函数测试 | constructorInlineCallInitOrder.kt, lambdaAddingThis.kt |
| Coroutines | 挂起函数测试 | suspendFunctionAsBooleanCallable.kt, suspendFunctionWithJvmStaticSupertype.kt |
编写新的黑盒测试时:
compiler/testData/codegen/box/ 下的相应功能目录下创建 Kotlin 文件。box() 函数,表示测试通过。注解保留的测试示例
某些测试涉及多个模块,用于验证增量编译、跨模块内联或二进制兼容性等功能。这些测试通常使用特殊的命名或目录结构来指示模块边界。
来自注解测试的示例
代码生成测试提供了一个关键的验证层,确保 Kotlin 代码在所有目标平台上都能正确编译并按预期运行。黑盒方法侧重于行为而非实现细节,允许编译器内部进行演进,同时保持与现有代码的兼容性。
这些测试是 Kotlin 编译器质量保证流程的重要组成部分,确保了语言功能在所有目标平台上的持续一致性。