2014-02-27 95 views
5

作爲CI設置的一部分,第一步是使用SBT dist創建一個包/罐子。以下步驟是對dist創建的罐子進行單元,集成和功能測試。在SBT中使用「sbt testOnly」從jar中運行測試?

SBT可以做到嗎?

通常我使用sbt testOnly "Unit.*",但在項目的環境中工作的。當已經有一個jar時,我找不到任何文檔顯示如何做到這一點。

我使用ScalaTest我知道有是它的一個運動員,我可以用http://www.scalatest.org/user_guide/using_the_runner。但如果可能的話,使用SBT會更簡單。

作爲一個例子,這樣的事情是什麼,我在尋找:

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

將我的測試中,甚至包括在罐子裏,當我使用以下命令:

sbt dist 

編輯

  1. 我創建了一個新的文件夾
  2. 我用下面的內容添加build.sbt

    name := "abc" 
    
    version := "1.0-SNAPSHOT" 
    
    scalaVersion := "2.10.0" 
    
  3. 我加入了lib文件夾,複製我的測試罐子進去

  4. 我跑sbt testOnly Unit.*

  5. 它找不到任何測試

EDIT 2

我試着用下面的 「正確」 的SBT文件:

name := "ihs2tests" 

version := "1.0-SNAPSHOT" 

scalaVersion := "2.10.0" 

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

和將test.jar轉移到項目的根目錄中。再次,沒有發現測試。

+1

這應該有助於你開始:http://stackoverflow.com/a/16409096/2197460。 –

+0

測試代碼通常不會包含在'dist' jar文件中,但@DaveSwartz的鏈接可能對此有所幫助。 –

+0

'sbt test:dist'呢?這不包括在(測試)dist jar中的測試嗎? –

回答

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源代碼和默認的sbt shell腳本,它在運行sbt啓動器jar之前會執行大量設置。

1

通常我使用sbt testOnly「Unit。*」,但它適用於項目環境。當已經有一個jar時,我找不到任何文檔顯示如何做到這一點。

在SBT的test - 家庭任務(與testOnly爲例)與compile的任務,通過sbt.inc.Analysis實例返回編譯的文件列表一起工作。我無法弄清楚如何修改它並將已更改的Analysis實例注入testOnly,以便知道我要運行的測試是否存在。

我正在提出另一個解決方案 - 一個把戲

封裝測試類的罐子test:package任務如下:

[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 

當你有試驗瓶,你可以執行命令行的測試框架,而不 SBT(我假設你使用ScalaTest給出了標籤,但我將使用Specs2)。請閱讀測試框架的文檔,瞭解如何使用它,對於Specs2,請參閱Console output中描述的specs2.run

從測試jar執行測試需要定義一個合適的CLASSPATH,這個合適的CLASSPATH可能很容易或不太容易。這就是SBT可以提供很大幫助的地方 - 管理依賴性和CLASSPATH。

創建另一個SBT項目並將測試罐保存在lib子目錄中以使其位於CLASSPATH上(如Unmanaged dependencies中所述)。

lib中的依賴關係發生在所有類路徑上(用於編譯,測試,運行和控制檯)。

添加樣例build.sbt您將測試框架定義爲項目的依賴項。對於Specs2它是如下(I用作the Specs2 home page描述的默認配置):

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

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

訣竅是執行主類的測試框架,例如的specs2.run for 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仍然向上。

+0

我將我的build.sbt和tests.jar複製到一個新項目中,但它試圖再次編譯它,所以很不幸,這不起作用 – user2668128

+0

再次給它一個鏡頭! –