You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin Multiplatform无法识别跨模块文件 测试注解报错排查

问题根因

三个核心问题导致报错:

  • 独立的sharedTests模块没有显式配置对:shared模块的依赖,Gradle跨模块代码访问必须手动声明依赖,不会自动关联同项目下的其他模块。
  • 测试依赖配置位置错误、冗余冲突:把平台专属的测试依赖堆在了顶层dependencies块,受KMP分源码集隔离机制限制,common源集无法获取这些依赖;同时混入了TestNG、重复的JUnit依赖,导致@Test这类注解出现匹配冲突。
  • 源码路径不符合KMP约定:如果测试文件没有放在对应源码集的默认检索路径下,IDE和编译器不会将其识别为可索引的测试代码,自然无法识别同项目代码、提示注解异常。
  • 额外隐患:测试类声明了带参构造函数,Kotlin Test框架要求测试类必须提供无参构造,后续运行时会直接抛实例化错误。
修复步骤
  1. 先确认根目录settings.gradle(或settings.gradle.kts)中已经包含两个模块的配置,缺失则补全:
include ':shared'
include ':sharedTests'
  1. 修正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依赖,这些都会导致冲突
  1. 把测试文件移动到KMP默认检索的对应路径下:
  • 跨平台通用的测试类(比如FirstTest.kt)放在sharedTests/src/commonTest/kotlin/目录下
  • Android专属测试代码放在sharedTests/src/androidTest/kotlin/
  • iOS专属测试代码放在sharedTests/src/iosTest/kotlin/
    不要自行创建不在源码集配置里的自定义目录存放代码,否则不会被IDE索引。
  1. 修正测试类写法,去掉带参构造,保证测试类有无参构造,参考:
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...
    }
}
  1. 同步修正shared模块的依赖配置,把之前堆在顶层dependencies块的安卓相关依赖移到对应源码集,避免依赖解析混乱:
  • 安卓相关的库依赖移到androidMain的dependencies块
  • Android测试用的JUnit依赖移到androidTest的dependencies块
  • 删掉顶层dependencies块里多余的重复依赖

配置完成后同步Gradle,触发IDE重新索引项目即可正常识别shared模块代码,测试注解也不会再报红。

内容的提问来源于stack exchange,提问作者jasiu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 10:24:22