[英]sbt doesn't correctly deal with resources in multi-module projects when running integration tests. Why?
我在sbt项目上具有以下配置:
moduleA
包含许多集成测试。 moduleB
(取决于moduleA
)。 包含一个reference.conf
文件; moduleC
(聚合moduleA
和moduleB
这是根)。 当我尝试运行it:test
我得到了错误,因为测试找不到在reference.conf
可用的值。 手动将reference.conf
复制到moduleA
使其起作用。
问题似乎很明显是由于某种原因(在根目录下)运行it:tests
时,sbt不够聪明,无法将reference.conf
添加到类路径中。
谁能推理出为什么会这样? sbt如何与类路径和类加载器一起工作? 它将仅将所有内容转储到单个类加载器中吗? 似乎并非如此。
谢谢
为了解决您的问题和评论,让我分解一下SBT对您的项目所做的事情。
ModuleC
是根项目,它聚合 ModuleA
和ModuleB
。 在SBT的上下文中, 聚合意味着在根项目上运行的任何命令也将在聚合的子项目上运行。 因此,例如,如果您在根模块上运行集成测试,那么您还将为其聚合模块运行集成测试。 但是,重要的是要了解这并非一次完成 :该命令在每个子项目上单独运行。
SBT必须解决的下一个问题是子项目的处理顺序。 在这种情况下,由于ModuleB
依赖 ModuleA
,因此它必须在处理ModuleA
之前先处理ModuleB
。 否则,如果它们之间没有依赖关系,则顺序将无关紧要, SBT很有可能会ModuleC
在ModuleC
的聚合列表中指定的顺序。
但是,一个子项目依赖另一个项目意味着什么? 这是类似于一个SBT项目和它的一个关系libraryDependencies
:因库必须提供给子项目,它的资源和类中指定的阶段(编译,测试,运行等提供的类路径)。
因此,当在ModuleC
上运行集成测试时, SBT将首先运行ModuleA
的集成测试。 由于ModuleA
在项目中没有其他依赖项,因此将对其进行处理, 而其classpath上没有任何其他子项目 。 (这就是为什么它不能访问ModuleB
一部分的reference.conf
文件的原因。)如果考虑一下,这是有道理的,因为否则,如果ModuleA
和ModuleB
相互依赖,那么您将无法解决- -egg情况,无法建立任何项目。
(顺便说一句,如果ModuleA
源代码尚未编译,则将在运行集成测试之前通过单独的编译过程对其进行编译。)
接下来,它将尝试处理ModuleB
,将ModuleA
的资源和类添加到其类路径中,因为它依赖于它们。
从您的描述看来, ModuleB
的reference.conf
文件中的至少某些配置设置应该属于ModuleA
,因为它需要在集成测试期间访问它们。 这是否意味着整个文件应属于ModuleA
取决于您。 但是,每个子项目都有可能拥有自己的reference.conf
文件资源(这是我假设您正在使用的Typesafe Config库的设计功能)。 属于ModuleA
的reference.conf
文件的任何配置设置也将可供ModuleB
,因为它取决于ModuleA
。 (如果您有多个reference.conf
文件,则唯一的问题取决于打包和释放ModuleC
。如果将所有子项目中的所有内容打包到一个JAR文件中,则需要合并各种例如,将reference.conf
文件放在一起。)
另一种可能性是,某些或所有集成测试实际上应该属于ModuleC
而不是ModuleA
或ModuleB
。 同样,做出此决定将取决于您的要求。 如果每个子项目在所有情况下都执行集成测试是有意义的,则将它们放在子项目中。 如果它们仅对整个已完成的项目有意义,则将它们放在ModuleC
。
您可能需要阅读SBT多项目构建的文档,以获取更多详细信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.