繁体   English   中英

在SBT中使用“sbt testOnly”从jar运行测试?

[英]Running tests from jar with “sbt testOnly” in SBT?

作为CI设置的一部分,第一步是使用SBT dist创建包/罐。 以下步骤是使用dist -created jar运行单元,集成和功能测试。

是否有可能用SBT做到这一点?

通常我使用sbt testOnly "Unit.*" ,但这适用于项目的上下文。 我找不到任何文档显示如何在已经有jar的情况下执行此操作。

我正在使用ScalaTest,我知道有一个跑步者,我可以使用http://www.scalatest.org/user_guide/using_the_runner 但是如果可能的话,使用SBT会更简单。

举个例子,我正在寻找这样的东西:

sbt testOnly "Unit.* -jar myjar.jar"

当我使用以下内容时,我的测试是否会包含在jar中:

sbt dist

编辑

  1. 我创建了一个新文件夹
  2. 我添加了build.sbt ,内容如下:

     name := "abc" version := "1.0-SNAPSHOT" scalaVersion := "2.10.0" 
  3. 我添加了lib文件夹并将我的测试jar复制到其中

  4. 我跑了sbt testOnly Unit.*

  5. 它找不到任何测试

编辑2

我尝试使用以下“正确”的SBT文件:

name := "ihs2tests"

version := "1.0-SNAPSHOT"

scalaVersion := "2.10.0"

unmanagedBase in Test := new java.io.File(".")

并将test.jar移动到项目的根目录中。 再次,没有发现任何测试。

通常我使用sbt testOnly“Unit。*”,但这适用于项目的上下文。 我找不到任何文档显示如何在已经有jar的情况下执行此操作。

SBT中的test -family任务(以testOnly为例)与compile任务一起工作,该任务通过sbt.inc.Analysis实例返回编译文件列表。 我无法弄清楚如何修改它并将已更改的Analysis实例注入testOnly因此它知道我将要运行的测试存在。

我提议另一种解决方案 - 一招

使用test:package任务将测试类打包到jar中,如下所示:

[test-lib]> test:package
[info] Updating {file:/Users/jacek/sandbox/so/test-lib/}test-lib...
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.
[info] Compiling 1 Scala source to /Users/jacek/sandbox/so/test-lib/target/scala-2.10/test-classes...
[info] Packaging /Users/jacek/sandbox/so/test-lib/target/scala-2.10/test-lib_2.10-0.1-SNAPSHOT-tests.jar ...
[info] Done packaging.
[success] Total time: 9 s, completed Mar 4, 2014 11:34:13 PM

当你有测试jar时,你可以在没有 SBT的情况下在命令行上执行测试框架(我假设你使用ScalaTest给出了标签,但我将使用Specs2)。 阅读测试框架的文档,了解如何执行此操作,并阅读Specs2的specs2.run ,如控制台输出中所述

从测试jar执行测试需要定义一个适当的CLASSPATH,可能很容易也可能不容易。 这就是SBT可以提供很大帮助的地方 - 管理依赖关系,从而管理CLASSPATH。

创建另一个SBT项目并将测试jar保存在lib子目录中以使其位于CLASSPATH上(如非托管依赖项中所述 )。

lib中的依赖关系遍历所有类路径(用于编译,测试,运行和控制台)。

添加一个示例build.sbt ,您可以将测试框架定义为项目的依赖项。 对于Specs2,它如下(我使用了Specs2主页中描述的默认配置):

libraryDependencies += "org.specs2" %% "specs2" % "2.3.8" % "test"

scalacOptions in Test ++= Seq("-Yrangepos")

诀窍是执行测试框架的主类,例如specs2.run的specs2.run,就像在命令行上执行类一样。 SBT帮助test:runMain

[my-another-project]> test:runMain specs2.run HelloWorldSpec
[info] Running specs2.run HelloWorldSpec
HelloWorldSpec

The 'Hello world' string should
+ contain 11 characters
+ start with 'Hello'
+ end with 'world'

Total for specification HelloWorldSpec
Finished in 62 ms
3 examples, 0 failure, 0 error

Exception: sbt.TrapExitSecurityException thrown from the UncaughtExceptionHandler in thread "run-main-0"
[success] Total time: 5 s, completed Mar 4, 2014 11:15:14 PM

不要担心这个Exception因为它来自SBT,它从Specs2中获取exit (在测试执行之后),因此SBT保持不变。

似乎SBT无法在没有任何额外/手动设置的情况下读取jar文件 - 我可能错了,但我没有在文档中找到任何内容。 所以我尝试了这样的事情来简化任务:

unzip some-test.jar

java -jar sbt-launch.jar \
  'set scalaSource in Test := new java.io.File(".")' \
  'set fullClasspath in Test += Attributed.blank(file("."))' \
  'test'

这运行没有错误,但没有找到测试。

如果我'set includeFilter in (Test, unmanagedSources) := "*Suite*.class"'添加'set includeFilter in (Test, unmanagedSources) := "*Suite*.class"'以强制它查找测试,它显然会失败,因为它需要*.scala文件,而不是编译的*.class文件。

我不是SBT专家,但我认为这必须接近解决方案。 必须有一种方法以编程方式从jar路径读取所有文件,然后告诉测试框架使用*.class文件。

在这一点上,使用Scalatest测试运行器或使用该项目从sbt运行测试似乎更合理。

如果你想深入挖掘,请查看SBT源代码和默认的sbt shell脚本,它在运行sbt启动程序jar之前进行大量设置。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM