Android Studio 3.0 Canary 1:Kotlin测试或Java测试引用Kotlin类失败

时间:2017-05-19 22:37:07

标签: java android android-studio junit kotlin

更新

此处已针对此问题提交了一个错误: https://youtrack.jetbrains.com/issue/KT-17951

更新2

该错误已在Android Studio 3.0 Canary 3中修复

原帖

我刚刚开始玩Android Studio 3.0我从一开始就启用了kotlin支持。我在我的项目中写了一个非常简单的Kotlin类:

data class Wallet(val coins: Int) {
    fun add(value: Int): Wallet = Wallet(coins + value)
    fun substract(value: Int): Wallet = if (coins > value) Wallet(coins + value) else throw InsufficientFundsException()
}

现在我想测试这个类,首先我在Kotlin写了一个本地运行的unittest(测试目录):

class WalletTestKotlin {

    @Throws(Exception::class)
    @Test
    fun add() {
        Assert.assertEquals(22, Wallet(20).add(2).coins.toLong())
        Assert.assertNotEquals(5, Wallet(2).add(13).coins.toLong())
    }
}

它编译并运行,但出现错误信息:

  

未找到班级:   " com.agentknopf.hachi.repository.model.WalletTestKotlin"空测试   套件。

因此我用Java重新编写了测试:

public class WalletTest {

    @Throws(exceptionClasses = Exception.class)
    @Test
    public void add() {
        Assert.assertEquals(22, new Wallet(20).add(2).getCoins());
        Assert.assertNotEquals(5, new Wallet(2).add(13).getCoins());
    }
}

然而,该测试也失败了 - 这次是Kotlin类" Wallet"无法找到:

  

java.lang.NoClassDefFoundError:com / example / repository / model / Wallet

我想知道我是否遗漏了某些东西......运行Java测试,不是指Kotlin类,而是仅仅成功完成Java类。

我的项目build.gradle文件是默认文件:

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    ext.kotlin_version = '1.1.2-4'
    repositories {
        maven { url 'https://maven.google.com' }
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.0.0-alpha1'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
        maven { url 'https://maven.google.com' }
        mavenCentral()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

我的特定于模块的build.gradle的依赖项:

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    //Kotlin support
    compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
    //Testing libraries
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    testCompile 'junit:junit:4.12'
    testCompile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    testCompile "org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version"
}

4 个答案:

答案 0 :(得分:15)

解决方法(暂时):

将它放入你的(app-level)build.gradle:

task copyTestClasses(type: Copy) {
    from "build/tmp/kotlin-classes/debugUnitTest"
    into "build/intermediates/classes/debug"
}

然后在启动之前在底部向下修改测试JUnit运行/调试配置'' Gradle-aware make'在其中,+另一部分,选择gradle task,选择其所在的项目build.gradle,然后输入copyTestClassesClick here for screenshots不同的测试框架,但管道的工作方式相同。

您可能需要根据构建类型更改/添加更多目录管道。找到这些奇怪位置的方法是通过粗略搜索项目树中的相关.class文件。

答案 1 :(得分:12)

  

注意:Android Studio 3.3 Canary已修复问题

感谢@kat向我展示正确的方向。首先 - 对于OP中提到的问题bug had been filed

我的设置如下:Kotlin Tests与Java测试位于同一目录中。要使两个用例都能正常工作:

  • 请参阅Java测试中的kotlin类
  • 参考kotlin测试中的kotlin课程

首先删除您可能拥有的任何其他测试运行配置。然后我在我的应用级build.gradle中添加了这两个gradle构建任务:

android {
    ...

    task copyTestClasses(type: Copy) {
        from "build/tmp/kotlin-classes/debugUnitTest"
        into "build/intermediates/classes/debug"
    }

    task copySdkClasses(type: Copy) {
        from "build/tmp/kotlin-classes/debug"
        into "build/intermediates/classes/debug"
    }
}

然后我通过Run>打开了运行配置菜单。编辑配置。在左侧我删除了顶级Android JUnit配置。 然后我点击默认值> Android JUnit并按如下方式编辑配置:

  • 测试种类=全包
  • 表单模式=无
  • 重复=一次
  • Package =我的基本软件包,如com.yourname
  • 在单个模块中搜索tests =
  • 我没有触及中间部分(VM选项等)
  • 在“发布前”部分中,点击加号图标添加两个条目:
  • 运行gradle任务:选择app模块的build.gradle,然后在任务中输入名称copyTestClasses并单击OK
  • 像以前一样添加第二个Run gradle任务,但这次作为任务名称输入copySdkClasses并单击OK
  • 单击配置上的应用,然后运行测试

最终看起来像这样:enter image description here

答案 2 :(得分:4)

@AgentKnopf恰到好处,但您需要在每个新的测试用例中添加任务,例如

enter image description here

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    androidTestCompile("com.android.support.test.espresso:espresso-core:$espresso_version", {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    testCompile "junit:junit:$junit_version"
    // kotlin
    compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
    ...............
}
// add 2 task in run config to make kotlin test working
// for junit
task copyTestClasses(type: Copy) {
    from "build/tmp/kotlin-classes/debugUnitTest"
    into "build/intermediates/classes/debug"
}
// for instrumented test
task copySdkClasses(type: Copy) {
    from "build/tmp/kotlin-classes/debug"
    into "build/intermediates/classes/debug"
}

afterEvaluate {
    compileDebugUnitTestSources.dependsOn copyTestClasses
    compileReleaseUnitTestSources.dependsOn copyTestClasses

    compileDebugAndroidTestSources.dependsOn copySdkClasses
}

自动为您添加任务

答案 3 :(得分:-1)

此错误已在Android Studio 3.0 Canary 3中修复