在SBT中使用“sbt testOnly”从jar中运行测试?
作为CI设置的一部分,第一步是使用SBT dist
创建一个包/罐子。 下面的步骤是与所述运行单元,集成和功能测试dist
-created罐子。
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
?
编辑
我添加了以下内容的build.sbt
:
name := "abc"
version := "1.0-SNAPSHOT"
scalaVersion := "2.10.0"
我添加了lib
文件夹并将我的测试jar复制到它中
我跑了sbt testOnly Unit.*
它找不到任何测试
编辑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
系列任务( 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给出了scalatest标签,但是我会使用Specs2)。 请阅读测试框架的文档,了解如何执行此操作,并参阅Specs2的specs2.run
,如控制台输出中所述。
从测试jar执行测试需要定义一个适当的CLASSPATH,这个CLASSPATH可能很容易或不太容易。 这就是SBT可以提供很大帮助的地方 - 管理依赖性和CLASSPATH。
创建另一个SBT项目并将测试jar保存在lib
子目录中以使其位于CLASSPATH上(如Unmanaged dependencies中所述)。
lib中的依赖关系发布在所有类路径上(用于编译,测试,运行和控制台)。
添加一个示例build.sbt
,在其中将您的测试框架定义为项目的依赖项。 对于Specs2,它如下所示(我使用Specs2主页中描述的默认配置):
libraryDependencies += "org.specs2" %% "specs2" % "2.3.8" % "test"
scalacOptions in Test ++= Seq("-Yrangepos")
诀窍是执行测试框架的主类,例如specs2.run
用于Specs2,就好像类在命令行上执行一样。 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之前进行大量设置。
上一篇: Running tests from jar with "sbt testOnly" in SBT?
下一篇: How to configure sbt test / ScalaTest to only show failures?