Kotlin Multiplatform无法识别跨模块文件 测试注解报错排查
问题根因
三个核心问题导致报错:
- 独立的
sharedTests模块没有显式配置对:shared模块的依赖,Gradle跨模块代码访问必须手动声明依赖,不会自动关联同项目下的其他模块。 - 测试依赖配置位置错误、冗余冲突:把平台专属的测试依赖堆在了顶层dependencies块,受KMP分源码集隔离机制限制,common源集无法获取这些依赖;同时混入了TestNG、重复的JUnit依赖,导致
@Test这类注解出现匹配冲突。 - 源码路径不符合KMP约定:如果测试文件没有放在对应源码集的默认检索路径下,IDE和编译器不会将其识别为可索引的测试代码,自然无法识别同项目代码、提示注解异常。
- 额外隐患:测试类声明了带参构造函数,Kotlin Test框架要求测试类必须提供无参构造,后续运行时会直接抛实例化错误。
修复步骤
- 先确认根目录
settings.gradle(或settings.gradle.kts)中已经包含两个模块的配置,缺失则补全:
include ':shared' include ':sharedTests'
- 修正
sharedTests模块的Gradle配置,在对应源码集中添加对shared模块的依赖,删除冗余冲突的测试依赖,不要把平台专属依赖堆在顶层dependencies块。参考配置如下:
plugins { kotlin("multiplatform") id("com.android.library") } kotlin { android() listOf( iosX64(), iosArm64(), iosSimulatorArm64() ).forEach { it.binaries.framework { baseName = "testModule" } } sourceSets { val commonMain by getting { dependencies { // 跨模块依赖shared主模块的commonMain代码 implementation(project(":shared")) } } val commonTest by getting { dependencies { implementation(kotlin("test")) // 测试代码也需要访问shared模块的代码 implementation(project(":shared")) } } val androidMain by getting val androidTest by getting { dependencies { // Android平台测试的JUnit依赖放在这里,不要放顶层 implementation(kotlin("test-junit")) } } val iosX64Main by getting val iosArm64Main by getting val iosSimulatorArm64Main by getting val iosMain by creating { dependsOn(commonMain) iosX64Main.dependsOn(this) iosArm64Main.dependsOn(this) iosSimulatorArm64Main.dependsOn(this) } val iosX64Test by getting val iosArm64Test by getting val iosSimulatorArm64Test by getting val iosTest by creating { dependsOn(commonTest) iosX64Test.dependsOn(this) iosArm64Test.dependsOn(this) iosSimulatorArm64Test.dependsOn(this) } } } android { compileSdk = 32 sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") defaultConfig { minSdk = 21 targetSdk = 32 } } // 删掉之前顶层dependencies里所有冗余的testng、重复junit、手动引入的kotlin-test-annotations依赖,这些都会导致冲突
- 把测试文件移动到KMP默认检索的对应路径下:
- 跨平台通用的测试类(比如
FirstTest.kt)放在sharedTests/src/commonTest/kotlin/目录下 - Android专属测试代码放在
sharedTests/src/androidTest/kotlin/ - iOS专属测试代码放在
sharedTests/src/iosTest/kotlin/
不要自行创建不在源码集配置里的自定义目录存放代码,否则不会被IDE索引。
- 修正测试类写法,去掉带参构造,保证测试类有无参构造,参考:
import kotlin.test.BeforeTest import kotlin.test.Test open class FirstTest { private lateinit var app: IAppWrapper // 如果需要传入平台侧的IAppWrapper实现,在各平台的测试子类中初始化即可,不要给父类加带参构造 @BeforeTest fun setUpTests(){ // 初始化app逻辑 } @Test fun testOne(){ //testing... } }
- 同步修正
shared模块的依赖配置,把之前堆在顶层dependencies块的安卓相关依赖移到对应源码集,避免依赖解析混乱:
- 安卓相关的库依赖移到
androidMain的dependencies块 - Android测试用的JUnit依赖移到
androidTest的dependencies块 - 删掉顶层dependencies块里多余的重复依赖
配置完成后同步Gradle,触发IDE重新索引项目即可正常识别shared模块代码,测试注解也不会再报红。
内容的提问来源于stack exchange,提问作者jasiu
相关产品推荐
相关产品推荐

