作为CI设置的一部分,第一步是使用SBT dist
创建包/ jar。以下步骤是使用dist
创建的jar运行单元,集成和功能测试。
用SBT可以做到吗?
通常我使用sbt testOnly "Unit.*"
,但这可以在项目的上下文中使用。我找不到任何文档显示如何在已经有罐子的情况下执行此操作。
我正在使用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
移到项目的根目录中。再次,没有发现任何测试。
答案 0 :(得分:1)
通常我使用sbt testOnly“Unit。*”,但这适用于项目的上下文。我找不到任何文档显示如何在已经有罐子的情况下执行此操作。
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 )。阅读测试框架的文档,了解如何执行此操作,并按照Console output中的描述阅读specs2.run
的Specs2。
从测试jar执行测试需要定义一个适当的CLASSPATH,可能很容易也可能不容易。这就是SBT可以提供很大帮助的地方 - 管理依赖关系,从而管理CLASSPATH。
创建另一个SBT项目并将测试jar保存在lib
子目录中以使其位于CLASSPATH上(如Unmanaged dependencies中所述)。
lib中的依赖关系遍历所有类路径(用于编译,测试,运行和控制台)。
添加样本build.sbt
,将测试框架定义为项目的依赖项。对于Specs2,它如下(我使用了the Specs2 home page中描述的默认配置):
libraryDependencies += "org.specs2" %% "specs2" % "2.3.8" % "test"
scalacOptions in Test ++= Seq("-Yrangepos")
技巧是执行测试框架的主类,例如对于Specs2,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保持运行。
答案 1 :(得分:0)
似乎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"'
以强制它查找测试,它显然会失败,因为它需要*.scala
个文件,而不是编译的*.class
文件。
我不是SBT专家,但我认为这必须接近解决方案。必须有一种方法以编程方式从jar路径读取所有文件,然后告诉测试框架使用*.class
文件。
此时使用Scalatest测试运行器或使用该项目从sbt运行测试似乎更合理。
如果您想深入挖掘,请查看SBT源代码和默认{{1}} shell脚本,该脚本在运行sbt启动程序jar之前进行大量设置。