如何保证编译和测试配置的相同库版本

问题描述 投票:1回答:1

我有一个中型sbt项目(~20个子项目,~50个直接依赖项,~400个传递依赖项)。我正在准备项目以启用单元测试[0]。我遇到了奇怪的问题,并注意到用于某些依赖关系的确切版本在CompileTest目标之间有所不同,即单元测试(sbt test)使用不同版本的库运行而不是项目(sbt run)。

我在sbt Compile/dependencyList [1]和sbt Test/dependencyList的输出之间产生了一个差异,并看到了50个不同版本的依赖关系。我知道我可以使用dependencyOverride设置,但手动执行数百个依赖项似乎不切实际。每次我们想要更新我们的直接依赖项时,我还必须更新该列表。

处理这种情况的预期方法是什么?即我如何确保在单元测试期间使用与在生产中运行时相同版本的依赖项?

[0]:迟到总比没有好! :)

[1]:dependencyList是来自sbt-dependency-graph的命令。

unit-testing dependencies sbt dependency-management
1个回答
1
投票

首先考虑确认依赖地狱是否确实是问题的原因。我们可能采用的一种方法是运行包含所有运行时依赖项的胖jar测试。

sbt-assembly添加到插件中,然后定义以下自定义命令:

commands += Command.command("testWithFatJar") { state =>
    "set assembly / test := {}" ::
    "assembly" ::
    "set Test / fullClasspath := Attributed.blank((assembly / assemblyOutputPath).value) :: (Test / fullClasspath).value.toList" ::
    "test" :: state
}

注意我们如何首先组装胖jar,然后将其添加到测试类路径中

Test / fullClasspath := Attributed.blank((assembly / assemblyOutputPath).value) :: (Test / fullClasspath).value.toList

这使它处于第一位置。在这里,我们利用JVM的classpath ordering属性

指定多个类路径条目的顺序很重要。 Java解释器将按照它们在类路径变量中出现的顺序查找目录中的类

这意味着如果我们在类路径上有相同的类,那么将使用遇到的第一个类。

脂肪罐的位置由assemblyOutputPath任务提供:

inspect assembly::assemblyOutputPath
[info] Task: java.io.File
[info] Description:
[info]  output path of the fat jar

现在执行testWithFatJar应运行以下测试类路径:

sbt:how-to-guarantee-same-library-versions-for-compile-and-test-configurations> show Test / fullClasspath
[info] * Attributed(/Users/mario_galic/code/stackoverflow/how-to-guarantee-same-library-versions-for-compile-and-test-configurations/target/scala-2.12/how-to-guarantee-same-library-versions-for-compile-and-test-configurations-assembly-0.1.0-SNAPSHOT.jar)
[info] * Attributed(/Users/mario_galic/code/stackoverflow/how-to-guarantee-same-library-versions-for-compile-and-test-configurations/target/scala-2.12/test-classes)
[info] * Attributed(/Users/mario_galic/code/stackoverflow/how-to-guarantee-same-library-versions-for-compile-and-test-configurations/target/scala-2.12/classes)
[info] * Attributed(/Users/mario_galic/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.12.8.jar)
[info] * Attributed(/Users/mario_galic/.ivy2/cache/org.scalatest/scalatest_2.12/bundles/scalatest_2.12-3.0.5.jar)
[info] * Attributed(/Users/mario_galic/.ivy2/cache/org.scalactic/scalactic_2.12/bundles/scalactic_2.12-3.0.5.jar)
[info] * Attributed(/Users/mario_galic/.ivy2/cache/org.scala-lang/scala-reflect/jars/scala-reflect-2.12.8.jar)
[info] * Attributed(/Users/mario_galic/.ivy2/cache/org.scala-lang.modules/scala-xml_2.12/bundles/scala-xml_2.12-1.0.6.jar)

注意*-assembly-0.1.0-SNAPSHOT.jar是如何处于第一位置的。一旦我们确认依赖地狱是原因,那么我们就可以开始考虑解决它所需的永久构建修改。

© www.soinside.com 2019 - 2024. All rights reserved.