有没有办法构建一个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
。
答案 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构建中如何工作的快速摘要是:
extendsFrom
主要配置(例如compile
),然后使用ResolutionStrategy#force
和ResolutionStrategy#forcedModules
到添加早期版本的配置依赖于该配置的依赖列表。sourceSets
中,将步骤1中创建的配置附加到您希望强制使用早期依赖项版本的目标的compileClasspath
和runtimeClasspath
。dependencies
中,添加较新版本的工件作为步骤2中创建的配置的依赖项。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'
}