首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何确保编译和测试配置的库版本相同

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

Stack Overflow用户
提问于 2019-04-15 09:56:50
回答 2查看 298关注 0票数 2

我有一个中等规模的sbt项目(20个子项目,50个直接依赖项,400个传递依赖项).我正在准备这个项目,以便进行单元测试。我遇到了一些奇怪的问题,并注意到用于某些依赖项的确切版本在CompileTest目标之间存在差异,即单元测试(sbt test)与项目直接(sbt run)不同版本的库一起运行。

我在sbt Compile/dependencyList 1和sbt Test/dependencyList的输出之间产生了差异,并看到了大约50个不同版本的依赖项。我知道我可以使用dependencyOverride设置,但是手动处理数百个依赖项似乎是不切实际的。每当我们想更新我们的直接依赖项时,我也必须更新这个列表。

处理这种情况的打算是什么?也就是说,如何确保在单元测试期间使用与在生产中运行时相同的依赖关系版本?

::迟到总比没有好!)

1:dependencyList是来自依赖关系图的命令。

EN

回答 2

Stack Overflow用户

发布于 2019-04-15 12:48:15

首先,考虑确认依赖地狱是否确实是问题的原因。我们可以这样做的一种方法是运行包含所有运行时依赖项的fat jar测试。

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

代码语言:javascript
复制
commands += Command.command("testWithFatJar") { state =>
    "set assembly / test := {}" ::
    "assembly" ::
    "set Test / fullClasspath := Attributed.blank((assembly / assemblyOutputPath).value) :: (Test / fullClasspath).value.toList" ::
    "test" :: state
}

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

代码语言:javascript
复制
Test / fullClasspath := Attributed.blank((assembly / assemblyOutputPath).value) :: (Test / fullClasspath).value.toList

使它处于第一位。这里我们利用JVM的类路径排序属性

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

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

胖罐子的位置由assemblyOutputPath任务提供:

代码语言:javascript
复制
inspect assembly::assemblyOutputPath
[info] Task: java.io.File
[info] Description:
[info]  output path of the fat jar

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

代码语言:javascript
复制
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在第一个位置上的位置。一旦我们确认依赖地狱是原因,那么我们就可以开始思考什么是永久构建修改才能解决这个问题。

票数 1
EN

Stack Overflow用户

发布于 2021-05-10 09:13:49

下面是我的脚本,它检测仅存在于生产配置中但不在测试配置中的依赖项(及其版本)。

它依赖于安装依赖图SBT插件

我将它集成到我们的CI中,如果只检测到任何生产依赖项,它就会使构建失败。

代码语言:javascript
复制
#!/bin/bash                                                                                                                                                                                             

# http://redsymbol.net/articles/unofficial-bash-strict-mode/                                                                                                                                            
set -euo pipefail
IFS=$'\n\t'

echo Getting dependencyList for production config
sbt "-Dsbt.log.noformat=true" dependencyList > dependency-list-production-raw.txt

echo Getting dependencyList for test config
sbt "-Dsbt.log.noformat=true" test:dependencyList > dependency-list-test-raw.txt

clean_up_dependency_list () {
  # non GNU sed version (less readable IMHO)                                                                                                                                                            
  # sed -n 's/[[:space:]]*\[info\][[:space:]]*\([^:]\{1,\}:[^:]\{1,\}:[^:]\{1,\}\)\s*$/\1/p' | sort | uniq                                                                                              
  sed --regexp-extended -n 's/^\s*\[info\]\s*([^:]+:[^:]+:[^:]+)\s*$/\1/p' | sort | uniq
}

clean_up_dependency_list < dependency-list-production-raw.txt > dependency-list-production.txt

clean_up_dependency_list < dependency-list-test-raw.txt > dependency-list-test.txt


echo Dependencies in dependency-list-production.txt: "$(wc -l < dependency-list-production.txt)"
echo Dependencies in dependency-list-test.txt: "$(wc -l < dependency-list-test.txt)"

dependencies_only_in_prod=$(comm -23 dependency-list-production.txt dependency-list-test.txt)

if [ -n "$dependencies_only_in_prod" ]; then
    cat <<EOF                                                                                                                                                                                           
                                                                                                                                                                                                        
    ERROR: Dependencies that are _not present in test_                                                                                                                                                  
    configuration detected!                                                                                                                                                                             
                                                                                                                                                                                                        
    This may signal a problem where a _different_ (older?) version of                                                                                                                                   
    a dependency will be used in production than what would be used in                                                                                                                                  
    production.                                                                                                                                                                                         
                                                                                                                                                                                                        
    Offending dependencies that are present  _only in prod_:                                                                                                                                            
                                                                                                                                                                                                        
$dependencies_only_in_prod                                                                                                                                                                              
                                                                                                                                                                                                        
    Full list of dependencies in test:                                                                                                                                                                  
                                                                                                                                                                                                        
$(cat dependency-list-test.txt)                                                                                                                                                                         
                                                                                                                                                                                                        
    List of dependencies in production:                                                                                                                                                                 
                                                                                                                                                                                                        
$(cat dependency-list-production.txt)                                                                                                                                                                   
                                                                                                                                                                                                        
EOF                                                                                                                                                                                                     

    exit 1
fi
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55686652

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档