我有一个简单的SBT项目,包括src/main/scala
中的一些Scala代码和src/test/scala
中的一些测试代码。我使用sbt-assembly
插件创建一个胖jar,以便部署到远程系统上。胖jar包含Scala项目的所有依赖项,包括Scala运行时本身。这一切都很有效。
现在我正试图找出一种方法可以对胖罐运行Scala测试。我尝试了一个显而易见的事情,创建一个新的配置扩展Test
配置并将dependencyClasspath
修改为胖JAR而不是默认值,但是这会失败因为(我假设因为)scala运行时是包含在胖jar中并以某种方式与已经加载的scala运行时发生冲突。
我的解决方案现在有效,但它有严重的缺点。我只是使用Fork.java
在org.scalatest.tools.Runner
运行器上调用Java,其类路径设置为包含测试代码和胖jar以及所有测试依赖项。缺点是没有SBT测试丰富度有效,没有testQuick
,没有testOnly
,测试失败报告在stdout上。
我的问题可以归结为:当这些测试不依赖于相应的SBT compile
输出时,如何使用SBT的测试命令来运行测试,而是依赖于包含所有scala运行时的胖JAR文件?
答案 0 :(得分:1)
这就是我的目标(对于 specs2,但可以调整)。这基本上就是你所说的 Fork 解决方案,但我想我会把它留在这里,以防有人想知道那可能是什么。不幸的是,我认为您不能作为 SBT 测试运行器“正式”运行它。我还应该补充一点,即使这是 Scala,您仍然需要 Fork.java,因为 Fork.scala 依赖于我似乎没有的 runner 类。
test.sbt(或 build.sbt,如果你想把一堆东西放在那里——如果你想组织,SBT 会读取根目录中的所有 .sbt 文件):
// Set up configuration for building a test assembly
Test / assembly / assemblyJarName := s"${name.value}-test-${version.value}.jar"
Test / assembly / assemblyMergeStrategy := (assembly / assemblyMergeStrategy).value
Test / assembly / assemblyOption := (assembly / assemblyOption).value
Test / assembly / assemblyShadeRules := (assembly / assemblyShadeRules).value
Test / assembly / mainClass := Some("org.specs2.runner.files")
Test / test := {
(Test / assembly).value
val assembledFile: String = (Test / assembly / assemblyOutputPath).value.getAbsolutePath
val minimalClasspath: Seq[String] = (Test / assembly / fullClasspath).value
.filter(_.metadata.get(moduleID.key).get.organization.matches("^(org\\.(scala-lang|slf4j)|log4j).*"))
.map(_.data.getAbsolutePath)
val runClass: String = (Test / assembly / mainClass).value.get
val classPath: Seq[String] = Seq(assembledFile) ++ minimalClasspath
val args: Seq[String] = Seq("-cp", classPath.mkString(":"), runClass)
val exitCode = Fork.java((Test / assembly / forkOptions).value, args)
if (exitCode != 0) {
throw new TestsFailedException()
}
}
Test / assembly / test := {}
build.sbt 中的变化:
lazy val root = (project in file("."))
.settings(/* your original settings are here */)
.settings(inConfig(Test)(baseAssemblySettings): _*) // enable assembling in test
答案 1 :(得分:0)
尝试像这样将胖子罐添加到测试类路径的第一个位置
#include <stdio.h>
#include "my_files.h"
int main(void)
{
printf("cpu_list[0] is %d\n", cpu_list[0]);
printf("cpu_list[1] is %d\n", cpu_list[1]);
not_main();
printf("cpu_list[0] is %d\n", cpu_list[0]);
printf("cpu_list[1] is %d\n", cpu_list[1]);
return 0;
}
这里assemblyOutputPath
给出了胖子罐的路径。我的理解是JVM会将遇到的first class加载到类路径中,因此实际上我们将测试胖子罐。
我们可以像这样在自定义命令Public void onNumberButtonClick(actionevent e) {
Button b = (button) e. Getsource() ;
AppentText(b.gettext());
}
中捕获这个想法
Test / fullClasspath := Attributed.blank((assembly / assemblyOutputPath).value) :: (Test / fullClasspath).value.toList
用testAgainstFatJar
检查胖子罐确实在第一位置