强制Gradle使用早期的依赖版本进行测试

时间:2015-09-09 14:07:22

标签: java gradle build.gradle dependency-management

有没有办法构建一个Gradle构建文件来强制测试阶段使用早期版本的依赖项而不是用于编译和打包的依赖项?

我正试图set up an HBase mini-cluster via HBaseTestingUtility来测试我的项目;不幸的是,HBaseTestingUtility依赖于旧版本的Guava(14.0.1似乎可以工作),而我的项目的其余部分使用18.0。以下是我的构建脚本的摘录,原样(我也使用Gradle test-sets plugin by unbroken-dome创建两组独立的测试):

plugins {
    id 'org.unbroken-dome.test-sets' version '1.2.0'
}

apply plugin: 'java'

ext.verGuava = '18.0'
ext.verGuavaTEST = '14.0.1'

testSets {
    testUnit { dirName = 'test/unit' }
    testIntegration { dirName = 'test/integration' }
}

configurations {
    provided
    provided {
        extendsFrom(compile)
    }
    testIntConf
    testIntConf {
        extendsFrom(provided)
        resolutionStrategy {
            force "com.google.guava:guava:${verGuavaTEST}"
            forcedModules = ["com.google.guava:guava:${verGuavaTEST}"]
        }
    }
}

sourceSets {
    main.compileClasspath += configurations.provided
    testUnit.compileClasspath += configurations.provided
    testUnit.runtimeClasspath += configurations.provided
    testIntegration.compileClasspath += configurations.testIntConf
    testIntegration.runtimeClasspath += configurations.testIntConf
}

dependencies {
    provided "org.apache.hbase:hbase-client:${verHBase}"
    provided "org.apache.hbase:hbase-common:${verHBase}"
    compile "org.testng:testng:${verTestNG}"
    testIntegrationCompile group:'org.apache.hadoop', name:'hadoop-common', version:"${verHadoop}", classifier: 'tests'
    testIntegrationCompile group:'org.apache.hbase', name:'hbase-server', version:"${verHBase}"
    testIntegrationCompile group:'org.apache.hbase', name:'hbase-server', version:"${verHBase}", classifier: 'tests'
    testIntegrationCompile group:'org.apache.hbase', name:'hbase-hadoop-compat', version:"${verHBase}"
    testIntegrationCompile group:'org.apache.hbase', name:'hbase-hadoop-compat', version:"${verHBase}", classifier: 'tests'
    testIntegrationCompile group:'org.apache.hbase', name:'hbase-hadoop2-compat', version:"${verHBase}"
    testIntegrationCompile group:'org.apache.hbase', name:'hbase-hadoop2-compat', version:"${verHBase}", classifier: 'tests'
    testIntegrationCompile group:'org.apache.hadoop', name:'hadoop-hdfs', version:"${verHadoop}"
    testIntegrationCompile group:'org.apache.hadoop', name:'hadoop-hdfs', version:"${verHadoop}", classifier: 'tests'
}

testUnit {
    useTestNG()
    logger.info "@@@ Classpath (UNIT testing): ${classpath.getFiles().collect({it.toString()}).inject('\n') {acc, next -> acc + next + '\n'}}"
    logger.info "@@@ SystemProps (UNIT testing): ${System.getProperties().collect({it.toString()}).inject('\n') {acc, next -> acc + next + '\n'}}"
}

testIntegration {
    useTestNG()
    systemProperty "java.net.preferIPv4Stack", "true"
    logger.info "@@@ Classpath (INTEGRATION testing): ${classpath.getFiles().collect({it.toString()}).inject('\n') {acc, next -> acc + next + '\n'}}"
    logger.info "@@@ SysProps (INTEGRATION testing): ${System.getProperties().collect({it.toString()}).inject('\n') {acc, next -> acc + next + '\n'}}"
}

当我通过这个脚本运行构建时,我得到以下输出,这似乎表明Guava 14.0.1 已添加到testIntegration目标的类路径,而不是替换< / em> Guava 18.0:

@@@ Classpath (UNIT testing):
/home/user/.gradle/caches/modules-2/files-2.1/com.google.guava/guava/18.0/cce0823396aa693798f8882e64213b1772032b09/guava-18.0.jar
@@@ Classpath (INTEGRATION testing):
/home/user/.gradle/caches/modules-2/files-2.1/com.google.guava/guava/18.0/cce0823396aa693798f8882e64213b1772032b09/guava-18.0.jar
/home/user/.gradle/caches/modules-2/files-2.1/com.google.guava/guava/14.0.1/69e12f4c6aeac392555f1ea86fab82b5e5e31ad4/guava-14.0.1.jar

这种行为可能是预期的; API表示ResolutionStrategy.force(...) 工件附加到要考虑的列表中。

如何指导Gradle完全从testIntegration目标的类路径中消除Guava 18.0?

我尝试更改sourceSets部分以使用 = 而不是 + = 分配类路径:

sourceSets {
    ...
    testIntegration.compileClasspath = configurations.testIntConf
    testIntegration.runtimeClasspath = configurations.testIntConf
}

就消除Guava 18.0(并保留14.0.1)而言,这具有预期效果,但由于某种原因,它似乎阻止Gradle检测testIntegration源文件的位置,因此{{ 1}}测试永远不会被编译或执行。

我还尝试了一些从继承配置中清除Guava的变体,如下所示:

testIntegration

以上(以及我尝试的所有其他变体)确实成功消除了类路径中Guava工件的重复,但它们似乎使configurations { provided provided { extendsFrom(compile) } testIntConf testIntConf { extendsFrom(provided.copy { exclude group:"com.google.guava", module:"guava" }) resolutionStrategy { force "com.google.guava:guava:${verGuavaTEST}" forcedModules = ["com.google.guava:guava:${verGuavaTEST}"] } } } 无效,因为已解析的工件始终是较新的版本( 18.0)甚至在resolutionStrategy

2 个答案:

答案 0 :(得分:1)

虽然也许不是最优雅的解决方案(我仍然对更干净的解决方案感兴趣,如果它存在),似乎有效的方法是创建一个完全独立的配置,其中包含较新的Guava依赖< strong> only ,然后使用FileCollection#minus从testIntegration目标本身的类路径中减去该配置。

首先,创建配置;我在这里称之为guava,因为它的唯一目的是包含我想要从testIntegration类路径中排除的Guava 18.0工件:

configurations {
    guava
    ...
}

(配置应该单独包含Guava工件,因此它应该 extendsFrom任何其他配置。)

其次,将要从类路径中排除的工件添加到新创建的配置的依赖关系列表中。在这种情况下,我知道主要配置将com.google.guava:guava解析为版本18.0,因此我将该版本的Guava添加到guava配置:

dependencies {
    guava group:'com.google.guava', name:'guava', version:"${verGuava}"
    ...
}

第三,在Gradle目标中的classpath上调用FileCollection#minus,其中要强制使用早期版本的依赖项,以便排除较新的依赖项。我的上述testIntegration块因此被转换:

testIntegration {
    classpath = classpath.minus(configurations.guava);
    ...
}

因此,在Gradle构建中如何工作的快速摘要是:

  1. 创建extendsFrom主要配置(例如compile),然后使用ResolutionStrategy#forceResolutionStrategy#forcedModules添加早期版本的配置依赖于该配置的依赖列表。
  2. 创建第二个配置,该配置不会从任何内容扩展,用于保存依赖项的较新版本。
  3. sourceSets中,将步骤1中创建的配置附加到您希望强制使用早期依赖项版本的目标的compileClasspathruntimeClasspath
  4. dependencies中,添加较新版本的工件作为步骤2中创建的配置的依赖项。
  5. 由于步骤1和3中执行的操作,目标块中的classpath现在包含默认依赖项的并集。要删除< em>较新的版本,将classpath设置为classpath.minus(newerDependencyConfiguration),其中newerDependencyConfiguration是在步骤2中创建的。{/ li>

答案 1 :(得分:1)

我遇到了同样的问题,但版本更简单。因为我没有区分集成测试和单元测试。使用它似乎给测试正确的番石榴依赖

   configurations {
        all{
            resolutionStrategy {
                force 'com.fasterxml.jackson.core:jackson-databind:2.4.4'
            }
        }
        testCompile{
            resolutionStrategy {
                force 'com.google.guava:guava:14.0.1'
            }
        }
    }
dependencies {
 testCompile group: 'org.apache.hbase', name: 'hbase-testing-util', version: '1.2.4'
}