【问题标题】:Can't compile tests with Robolectric无法使用 Robolectric 编译测试
【发布时间】:2014-12-04 04:45:46
【问题描述】:

我的 build.gradle:

buildscript {
    repositories {
        mavenCentral()
    }

    dependencies {
        classpath 'com.stanfy.spoon:spoon-gradle-plugin:0.10.0'
    }
}


apply plugin: 'android-sdk-manager'
apply plugin: 'android'
apply plugin: 'spoon'
apply plugin: 'robolectric'

android {
    compileSdkVersion 19
    buildToolsVersion '20.0.0'

    defaultConfig {
        minSdkVersion 14
        targetSdkVersion 19
        testInstrumentationRunner 'com.google.android.apps.common.testing.testrunner.GoogleInstrumentationTestRunner'
    }


    buildTypes {
        debug {
        }
        release {
        }
    }

    productFlavors {
        first {
        //just version codes and packages
        }
        second {
        //just version codes and packages
        }
        third {
        //just version codes and packages  
        }
    }
}

spoon {
    debug = true
}

dependencies {
    compile project(':app:libs:facebookSDK')
    compile 'com.google.android.gms:play-services:5.0.89'
    compile 'com.android.support:support-v4:20.0.0+'
    compile 'com.google.code.gson:gson:2.2.4'
    compile fileTree(dir: 'libs', include: '*.jar')
    androidTestCompile fileTree(dir: 'libsTest', include: '*.jar')
    androidTestCompile 'com.squareup.spoon:spoon-client:1.1.0'
    androidTestCompile 'junit:junit:4.+'
    androidTestCompile 'org.robolectric:robolectric:2.3'
}

libsTest:espresso-contrib-1.1-bundled.jar

现在,我的错误如下:

Error Code:
    2
  Output:
    UNEXPECTED TOP-LEVEL EXCEPTION:
    com.android.dex.DexException: Multiple dex files define Lorg/hamcrest/SelfDescribing;
      at com.android.dx.merge.DexMerger.readSortableTypes(DexMerger.java:594)
      at com.android.dx.merge.DexMerger.getSortedTypes(DexMerger.java:552)
      at com.android.dx.merge.DexMerger.mergeClassDefs(DexMerger.java:533)
      at com.android.dx.merge.DexMerger.mergeDexes(DexMerger.java:170)
      at com.android.dx.merge.DexMerger.merge(DexMerger.java:188)
      at com.android.dx.command.dexer.Main.mergeLibraryDexBuffers(Main.java:439)
      at com.android.dx.command.dexer.Main.runMonoDex(Main.java:287)
      at com.android.dx.command.dexer.Main.run(Main.java:230)
      at com.android.dx.command.dexer.Main.main(Main.java:199)
      at com.android.dx.command.Main.main(Main.java:103)

更详细的日志在这里:

http://pastebin.com/Yye3cd1c

我该如何解决这个问题?

UPD:我现在的问题基本上是如何寻找那些重复的部分?

【问题讨论】:

  • 一般来说,这意味着这个类出现在构建路径中的多个位置(尽管它被明确排除在 junit 的依赖子句中)。我无法在我的设置中重现它;您能否在 libsTest 和 libs 文件夹中包含有关所有库的更多信息?这可能是罪魁祸首。
  • @ScottBarta 我已经更新了我的问题。
  • 我仍然无法重现。您将不得不四处寻找并找到复制该课程的地方。

标签: android junit gradle android-studio robolectric


【解决方案1】:

前段时间我遇到过类似的问题,如果我没记错的话,我通过添加如下的排除语句来修复它:

androidTestCompile('junit:junit:4.+') {
    exclude module: 'hamcrest-core'
}

【讨论】:

    【解决方案2】:

    deckard-gradle sample project 的启发,我建议尝试这样的事情:

    androidTestCompile 'org.hamcrest:hamcrest-integration:1.1'
    androidTestCompile 'org.hamcrest:hamcrest-core:1.1'
    androidTestCompile 'org.hamcrest:hamcrest-library:1.1'
    
    androidTestCompile('junit:junit:4.11') {
        exclude module: 'hamcrest-core'
    }
    androidTestCompile('org.robolectric:robolectric:2.3') {
        exclude module: 'classworlds'
        exclude module: 'commons-logging'
        exclude module: 'httpclient'
        exclude module: 'maven-artifact'
        exclude module: 'maven-artifact-manager'
        exclude module: 'maven-error-diagnostics'
        exclude module: 'maven-model'
        exclude module: 'maven-project'
        exclude module: 'maven-settings'
        exclude module: 'plexus-container-default'
        exclude module: 'plexus-interpolation'
        exclude module: 'plexus-utils'
        exclude module: 'wagon-file'
        exclude module: 'wagon-http-lightweight'
        exclude module: 'wagon-provider-api'
    }
    

    【讨论】:

      【解决方案3】:

      我现在的问题基本上是如何寻找那些重复的部分?

      您使用日志执行此操作。您粘贴的日志说:

      com.android.dex.DexException: 多个 dex 文件定义

      这很可能是由于冲突库。日志继续:

      Lorg/hamcrest/SelfDescribeing;

      这是冲突的库,hamcrest

      在你的项目中添加依赖后,如果有你的库(或作为你的库)使用的公共子库,就会出现这个错误。因此,hamcrest 似乎不仅被您的一个库使用。

      我们将通过检查依赖关系来了解这种冲突。当然,有效的检查需要同时直观和理性。

      让我们从 hamcrest 本身开始。 (我假设你以前没有听说过 hamcrest。)

      我们来看看Hamcrest project page。 Hamcrest 将自己定义为用于构建测试表达式的匹配器库。并且定义说典型场景包括测试框架、模拟库...这很有启发性,因为您对 JUnit、Espresso 和 Robolectric 等测试有一些依赖项。

      现在我们应该继续使用 JUnit dependencies。似乎 JUnit 使用了 hamcrest-coreHere 是我们的第一个 hamcrest 作为子依赖项。

      让我们继续使用 Espresso,因为您在 libsTest 文件夹中有 espresso-contrib-1.1-bundled.jar。 当我们查看 espresso-contrib 项目 dependencies 时,我们可以看到 Espresso 大量使用了 hamcrest。

      我们可能在您的项目中遇到了冲突的库,最后一步是在添加此依赖项时从我们的一个依赖项中排除 hamcrest-core。您可以通过以下方式实现:

      androidTestCompile('junit:junit:4.+') {
          exclude module: 'hamcrest-core'
      }
      

      【讨论】:

        【解决方案4】:

        寻找这些错误的一个技巧是使用 Android Studio 的“Navigate > Class...”选项。

        鉴于您有此错误:

        Lorg/hamcrest/SelfDescribing;
        

        然后您可以搜索“org.hamcrest.SelfDescribing”,以便了解使用它的 .jars。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-08-19
          • 2012-10-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-02-17
          相关资源
          最近更新 更多