Project Icon

kotlin-compile-testing

轻松实现Kotlin和Java代码编译测试

Kotlin-compile-testing是一个专为Kotlin和Java代码内部编译设计的开源库。它支持混合源集编译、注解处理和类路径继承,适用于测试注解处理器、编译器插件和代码生成。该库兼容Project Jigsaw,支持跨JDK编译,简化了编译测试流程,提升开发效率。多个知名开源项目已采用此库进行测试。

# Kotlin 编译测试 [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.tschuchortdev/kotlin-compile-testing/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.tschuchortdev/kotlin-compile-testing) ![GitHub](https://yellow-cdn.veclightyear.com/835a84d5/01ec6108-c7b7-4282-bda6-bd0a353107c7.svg?color=green&style=popout) [![欢迎贡献](https://yellow-cdn.veclightyear.com/835a84d5/127b1ea3-c0dc-4f15-9ab8-f4d2d2442f64.svg)](https://shields.io/) [![构建状态](https://yellow-cdn.veclightyear.com/835a84d5/cbef1f2f-43d8-4eb9-9c46-b6d12fde5066.svg)](https://github.com/tschuchortdev/kotlin-compile-testing/actions) 这是一个用于进行Kotlin和Java代码进程内编译的库,其灵感来源于[Google Compile Testing](https://github.com/google/compile-testing)。例如,您可以使用此库来测试您的注解处理器或编译器插件。 ## 用例 - 在测试中编译 Kotlin 和 Java 代码 - 测试注解处理器 - 测试编译器插件 - 测试 Kotlin 代码生成 ## 示例 创建源文件 ```Kotlin class TestEnvClass {}

@Test fun 测试我的注解处理器() { val kotlinSource = SourceFile.kotlin( "KClass.kt", """ class KClass { fun foo() { // 测试环境中的类对编译的源文件是可见的 val testEnvClass = TestEnvClass() } } """ )

val javaSource = SourceFile.java( "JClass.java", """ public class JClass { public void bar() { // 编译的Kotlin类对Java源文件是可见的 KClass kClass = new KClass(); } } """)

配置编译
```Kotlin
val result = KotlinCompilation().apply {
sources = listOf(kotlinSource, javaSource)

// 传入你自己的注解处理器实例
annotationProcessors = listOf(MyAnnotationProcessor())

// 传入你自己的编译器插件实例
compilerPlugins = listOf(MyComponentRegistrar())
commandLineProcessors = listOf(MyCommandlineProcessor())

inheritClassPath = true
messageOutputStream = System.out // 实时查看诊断信息
}.compile()

断言结果

assertThat(result.exitCode).isEqualTo(ExitCode.OK)

// 测试编译器的诊断输出
assertThat(result.messages).contains("我的注解处理器被调用了")

// 加载编译后的类并通过反射检查生成的代码
val kClazz = result.classLoader.loadClass("KClass")
assertThat(kClazz).hasDeclaredMethods("foo")
}

特性

  • 混合源代码集:在单次运行中编译Kotlin和Java源文件
  • 注解处理:
  • 对Kotlin和Java源代码运行注解处理器
  • 生成Kotlin和Java源代码
  • Kotlin和Java源代码都可以访问生成的源代码
  • 直接向编译器提供自定义的注解处理器实例,而不是让编译器使用服务定位器创建它们
  • 调试注解处理器:由于编译在与应用程序相同的进程中运行,您可以轻松调试它,而不必手动将IDE的调试器附加到编译过程
  • 继承类路径:编译后的源代码可以访问应用程序中的类
  • 兼容Project Jigsaw:Kotlin-Compile-Testing可以与JDK 8以及JDK 9及更高版本一起使用
  • JDK跨版本编译:提供自己的JDK来编译代码,而不是使用主机应用程序的JDK。这使您可以轻松测试所有JDK版本上的代码
  • 在主机类路径上自动查找依赖项

安装

该软件包可在 Maven Central 上获取。 在模块的 build.gradle 文件中添加依赖项:

dependencies {
// ...
testImplementation("com.github.tschuchortdev:kotlin-compile-testing:1.5.0")
}

如果觉得有用,请记得点个星

兼容的编译器版本

Kotlin-Compile-Testing 与所有本地编译器版本兼容。您用于编译项目的编译器版本并不重要。 然而,如果您的项目或其任何依赖项直接依赖于编译器构件,如 kotlin-compiler-embeddablekotlin-annotation-processing-embeddable,那么它们的版本必须与 Kotlin-Compile-Testing 使用的版本相同,否则将出现传递依赖冲突。

  • 当前 kotlin-compiler-embeddable 版本:1.9.24 由于 Kotlin 编译器的内部 API 在不同版本之间经常发生变化,我们一次只能支持一个 kotlin-compiler-embeddable 版本。

Kotlin 符号处理 API 支持

Kotlin 符号处理(KSP)是一种新的注解处理管道,它构建在 Kotlin 编译器的插件架构之上,而不是像 kapt 那样委托给 javac。

要测试 KSP 处理器,您需要使用 KSP 依赖:

dependencies {
    testImplementation("com.github.tschuchortdev:kotlin-compile-testing-ksp:1.6.0")
}

这个模块为 KotlinCompilation 添加了一个新函数,用于指定 KSP 处理器:

class MySymbolProcessorProvider : SymbolProcessorProvider {
    // KSP API 中 SymbolProcessorProvider 的实现
}

val compilation = KotlinCompilation().apply {
    sources = listOf(source)
    symbolProcessorProviders = listOf(MySymbolProcessorProvider())
}
val result = compilation.compile()

KSP 处理器生成的所有代码都将写入 KotlinCompilation.kspSourcesDir 目录。

使用Kotlin-Compile-Testing的项目

Java 16 兼容性

随着Java 16的发布,新的Jigsaw模块系统的访问控制开始由JVM强制执行。不幸的是,这对kotlin-compile-testing造成了影响,因为KAPT仍然试图访问jdk.compiler模块未导出的javac类,导致出现如下错误:

java.lang.IllegalAccessError: class org.jetbrains.kotlin.kapt3.base.KaptContext (in unnamed module @0x43b6aa9d) cannot access class com.sun.tools.javac.util.Context (in module jdk.compiler) because module jdk.compiler does not export com.sun.tools.javac.util to unnamed module @0x43b6aa9d

为了缓解这个问题,你需要在模块的build.gradle文件中添加以下代码:

if (JavaVersion.current() >= JavaVersion.VERSION_16) {
    test {
        jvmArgs(
            "--add-opens=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED",
            "--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED",
            "--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED",
            "--add-opens=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED",
            "--add-opens=jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED",
            "--add-opens=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED",
            "--add-opens=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED",
            "--add-opens=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED",
            "--add-opens=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED",
            "--add-opens=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
        )
    }
}

或者对于Kotlin DSL:

if (JavaVersion.current() >= JavaVersion.VERSION_16) {
    tasks.withType<Test>().all {
        jvmArgs(
            "--add-opens=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED",
            "--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED",
            "--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED",
            "--add-opens=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED",
            "--add-opens=jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED",
            "--add-opens=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED",
            "--add-opens=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED",
            "--add-opens=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED",
            "--add-opens=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED",
            "--add-opens=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED",
        )
    }
}

由于Kotlin编译测试在与测试运行器相同的进程中运行,这些选项必须手动添加,kotlin-compile-testing库无法自动设置。

许可证

版权所有 (C) 2023 Thilo Schuchort 根据Mozilla公共许可证2.0授权 如需定制许可协议,请直接与我联系

项目侧边栏1项目侧边栏2
推荐项目
Project Cover

豆包MarsCode

豆包 MarsCode 是一款革命性的编程助手,通过AI技术提供代码补全、单测生成、代码解释和智能问答等功能,支持100+编程语言,与主流编辑器无缝集成,显著提升开发效率和代码质量。

Project Cover

AI写歌

Suno AI是一个革命性的AI音乐创作平台,能在短短30秒内帮助用户创作出一首完整的歌曲。无论是寻找创作灵感还是需要快速制作音乐,Suno AI都是音乐爱好者和专业人士的理想选择。

Project Cover

有言AI

有言平台提供一站式AIGC视频创作解决方案,通过智能技术简化视频制作流程。无论是企业宣传还是个人分享,有言都能帮助用户快速、轻松地制作出专业级别的视频内容。

Project Cover

Kimi

Kimi AI助手提供多语言对话支持,能够阅读和理解用户上传的文件内容,解析网页信息,并结合搜索结果为用户提供详尽的答案。无论是日常咨询还是专业问题,Kimi都能以友好、专业的方式提供帮助。

Project Cover

阿里绘蛙

绘蛙是阿里巴巴集团推出的革命性AI电商营销平台。利用尖端人工智能技术,为商家提供一键生成商品图和营销文案的服务,显著提升内容创作效率和营销效果。适用于淘宝、天猫等电商平台,让商品第一时间被种草。

Project Cover

吐司

探索Tensor.Art平台的独特AI模型,免费访问各种图像生成与AI训练工具,从Stable Diffusion等基础模型开始,轻松实现创新图像生成。体验前沿的AI技术,推动个人和企业的创新发展。

Project Cover

SubCat字幕猫

SubCat字幕猫APP是一款创新的视频播放器,它将改变您观看视频的方式!SubCat结合了先进的人工智能技术,为您提供即时视频字幕翻译,无论是本地视频还是网络流媒体,让您轻松享受各种语言的内容。

Project Cover

美间AI

美间AI创意设计平台,利用前沿AI技术,为设计师和营销人员提供一站式设计解决方案。从智能海报到3D效果图,再到文案生成,美间让创意设计更简单、更高效。

Project Cover

AIWritePaper论文写作

AIWritePaper论文写作是一站式AI论文写作辅助工具,简化了选题、文献检索至论文撰写的整个过程。通过简单设定,平台可快速生成高质量论文大纲和全文,配合图表、参考文献等一应俱全,同时提供开题报告和答辩PPT等增值服务,保障数据安全,有效提升写作效率和论文质量。

投诉举报邮箱: service@vectorlightyear.com
@2024 懂AI·鲁ICP备2024100362号-6·鲁公网安备37021002001498号