簡體   English   中英

如何使用 SBT 對胖罐運行 ScalaTest 測試?

[英]How to use SBT to run ScalaTest tests against a fat jar?

我有一個簡單的 SBT 項目,由src/main/scala的一些 Scala 代碼和src/test/scala一些測試代碼組成。 我使用sbt-assembly插件來創建一個用於部署到遠程系統的胖 jar。 胖 jar 包含 Scala 項目的所有依賴項,包括 Scala 運行時本身。 這一切都很好。

現在我正試圖找出一種方法,我可以針對胖罐運行 Scala 測試。 我嘗試了顯而易見的事情,創建一個擴展Test配置的新配置並將dependencyClasspath路徑修改為胖 JAR 而不是默認值,但是這失敗了,因為(我假設是因為)Scala 運行時包含在胖 jar 中並以某種方式發生沖突使用已經加載的 Scala 運行時。

我的解決方案現在有效,但它有嚴重的缺點。 我只是用Fork.java調用Java的org.scalatest.tools.Runner亞軍與類路徑設置為包含測試代碼和脂肪的罐子和所有的測試依賴。 缺點是 SBT 測試豐富性都testQuick ,沒有testQuick ,沒有testOnly ,並且測試失敗報告在標准輸出上。

我的問題歸結為:當這些測試不依賴於相應的 SBT compile輸出,而是依賴於本身包含所有 Scala 運行時的胖 JAR 文件時,如何使用 SBT 的測試命令來運行測試?

這就是我的目標(對於 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

嘗試將胖子罐添加到測試類路徑的第一個位置,如下所示

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

在這里, assemblyOutputPath給出了胖子罐子的路徑。 我的理解是JVM將在路徑上遇到的第一個類加載,因此實際上我們將測試胖子罐。

我們可以像這樣在自定義命令testAgainstFatJar捕獲這個想法

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

使用show Test / fullClasspath檢查胖罐是否確實在第一個位置

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM