scala - 如何使用 SBT 对 fat jar 运行 ScalaTest 测试?

标签 scala sbt scalatest sbt-assembly

我有一个简单的 SBT 项目,由 src/main/scala 中的一些 Scala 代码和 src/test/scala 中的一些测试代码组成。我使用 sbt-assembly 插件来创建一个用于部署到远程系统的 fat jar。 fat jar 包含 Scala 项目的所有依赖项,包括 Scala 运行时本身。这一切都很好。

现在我正试图找到一种方法来对 fat jar 运行 Scala 测试。我尝试了显而易见的事情,创建了一个扩展 Test 配置的新配置并将 dependencyClasspath 修改为胖 JAR 而不是默认值,但是这失败了,因为(我假设因为)Scala 运行时包含在 fat jar 中,并以某种方式与已经加载的 Scala 运行时发生冲突。

我的解决方案现在可行,但它有严重的缺点。我只是使用 Fork.javaorg.scalatest.tools.Runner runner 上调用 Java,类路径设置为包括测试代码和 fat jar 以及所有的测试依赖关系。缺点是 SBT 测试丰富性都不起作用,没有 testQuick,没有 testOnly,测试失败报告在标准输出上。

我的问题归结为:当这些测试不依赖于相应的 SBT compile 输出,而是依赖于本身包含所有内容的胖 JAR 文件时,如何使用 SBT 的测试命令来运行测试Scala 运行时?

最佳答案

这就是我的目标(针对 specs2,但可以进行调整)。这基本上就是您所说的 Fork 解决方案,但我想我会把它留在这里,以防有人想知道那可能是什么。不幸的是,我认为您不能将其作为 SBT 测试运行器“正式”运行。我还应该补充一点,即使这是 Scala,您仍然需要 Fork.java,因为 Fork.scala 依赖于我似乎没有的运行器类。

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

关于scala - 如何使用 SBT 对 fat jar 运行 ScalaTest 测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38271431/

相关文章:

ScalaTest 相当于 JUnit 的套件?

scalatest - 如何使用 ScalaMock 代理模拟?

scala - Play Framework 异步 Controller 阻止对同一 Controller 的后续调用

scala - 了解 Scala 类型参数化中的多种参数类型

scala - 为什么 scala 允许对字符串中的单引号进行转义?

scala - Play : error: not found: value playScalaSettings

scala - 由于 Unresolved 依赖关系,无法构建 sbt 0.12.0-RC1

scala - 正则表达式中的某些内容破坏了我的 build.sbt 脚本(sbt 0.13,Scala 2.10.2)

ScalaTest:BeforeAndAfter 未运行

scala - 使用 scala 将数据帧列名称作为参数传递给函数?