菜单

测试基础设施

相关源文件

本文档全面概述了 Kotlin 编译器的测试基础设施,该基础设施可确保编译器在不同前端和后端目标上的正确性和可靠性。该测试系统旨在通过针对诊断、代码生成和各种编译器组件的广泛自动化测试来验证编译器行为。

概述

Kotlin 编译器的测试基础设施包含一个复杂的框架,该框架能够对编译器组件进行多维度的系统化验证。

  • 编译器管道阶段:前端(解析、求解)、中间件(IR 转换)和后端(代码生成)
  • 多个前端:K1(旧版)和 K2/FIR(新的 Kotlin 前端)
  • 目标平台:JVM、JavaScript、WebAssembly 和 Native
  • 测试类别:诊断、黑盒代码生成和其他专业测试

来源

测试生成系统

Kotlin 中的测试主要通过测试数据文件自动生成。测试生成器处理这些文件并生成 JUnit 测试类,然后将这些类作为构建和 CI 过程的一部分执行。

来源

测试生成系统使用几个关键组件

  1. 测试数据文件:包含测试用例的 Kotlin 源文件,位于 compiler/testData/diagnostics/tests/ 等目录中
  2. 生成器脚本:处理测试数据并生成测试类的代码
  3. 基础测试类:提供通用测试功能的抽象类
  4. 生成的测试类:包含实际测试方法的 Java 类

每个生成的测试类通常遵循此模式

  • 继承特定于测试类别的抽象基础测试类
  • 使用 @TestMetadata 注释链接到测试数据位置
  • 包含用于组织测试的嵌套类
  • 包含调用 runTest 方法并传入测试数据文件路径的测试方法

主要测试类别

诊断测试

诊断测试验证编译器正确检测和报告错误的能力。它们检查

  • 正确的诊断被报告在正确的位置
  • 没有假阳性或假阴性
  • 错误消息恰当且有帮助

针对不同的前端(K1/旧版和 K2/FIR)、测试方法(例如,反向测试)和解析器实现(基于 PSI 和基于 LightTree)有各种诊断测试。

来源

黑盒代码生成测试

黑盒代码生成测试用于验证编译器是否为不同的目标平台正确生成了可执行代码。这些测试

  • 编译 Kotlin 源代码
  • 执行编译后的代码
  • 验证结果是否与预期输出一致

所有编译器后端都存在黑盒测试

来源

测试数据组织

测试数据以分层的目录结构组织,每个目录包含特定功能或组件的测试文件。

诊断测试数据

诊断测试用于验证编译器错误报告。每个测试文件包含带有故意错误或缺陷的 Kotlin 代码,并且预期的诊断会使用特殊的注释语法在文件中进行标记。

目录:compiler/testData/diagnostics/tests/

黑盒测试数据

黑盒测试用于检查编译后的代码是否能正确运行。这些测试通常遵循一个模式,即成功的测试会从 box() 函数返回“OK”。

目录:compiler/testData/codegen/box/

测试数据目录的结构反映了所测试的功能,其中包含特定类别的子目录,例如

  • annotations
  • collections
  • controlFlow
  • dataClasses
  • functions
  • 等等。

测试执行流程

测试执行过程包括从定位测试数据到报告结果的多个步骤

来源

测试基础设施架构

测试基础设施由几个关键组件组成,这些组件协同工作以提供全面的测试。

来源

与构建系统的集成

测试基础设施通过 Gradle 与 Kotlin 构建系统集成。测试作为构建过程和 CI 的一部分运行,并以标准的 JUnit XML 格式报告测试结果。

构建集成的主要方面

  • 测试在构建期间自动生成
  • 测试可以有选择性地运行或分组运行
  • 支持并行测试执行
  • 收集和报告测试结果

编写新测试

要创建新测试,开发人员会将测试数据文件添加到相应的目录中。测试生成器会处理这些文件,从而在生成的测试类中创建测试方法。

对于诊断测试,开发人员会编写带有故意引入错误的代码,并使用特殊注释标记预期错误。

对于黑盒测试,开发人员会编写带有 box() 函数的 Kotlin 代码,该函数在测试通过时返回“OK”,在测试失败时返回错误消息。

跨前端和跨平台测试

测试基础设施支持跨不同 Kotlin 编译器前端和后端目标进行全面测试。

来源

此测试矩阵可确保 Kotlin 代码在所有支持的平台和两种编译器前端上都能正确运行,从而全面覆盖编译器的功能。