2011-10-26 113 views
4

怎樣才能增加對外依存度爲SBT插件,並使其可在這兩個項目和插件的類路徑:SBT:插件依賴關係和項目的classpath

具體來說,我有一個簡單的插件,它應該運行我們的TestNG的測試套房並做一些後期處理。這裏是一個簡化的版本:

import sbt._ 
import java.util.ArrayList 
import Keys._ 
import org.testng._ 

object RunTestSuitesPlugin extends Plugin { 
    lazy val runTestSuites = TaskKey[Unit]("run-test-suites", "runs TestNG test suites") 
    lazy val testSuites = SettingKey[Seq[String]]("test-suites", "list of test suites to run") 

    class JavaListWrapper[T](val seq: Seq[T]) { 
    def toJavaList = seq.foldLeft(new java.util.ArrayList[T](seq.size)) { (al, e) => al.add(e); al } 
    } 
    implicit def listToJavaList[T](l: Seq[T]) = new JavaListWrapper(l) 

    def runTestSuitesTask = runTestSuites <<= (target, streams, testSuites) map { 
    (targetDirectory, taskStream, suites) => 
     import taskStream.log 
     log.info("running test suites: " + suites) 
     runSuites(suites) 
    } 

    private def runSuites(testSuites: Seq[String]) = { 
    var tester = new TestNG 
    tester.setTestSuites(testSuites.toJavaList) 
    tester.run() 
    } 

    def testSuiteSettings = { 
    inConfig(Compile)(Seq(
     runTestSuitesTask, 
     testSuites := Seq("testsuites/mysuite.xml"), 
     libraryDependencies += "org.testng" % "testng" % "5.14")) 
    } 
} 

的問題是,當我這個插件添加到項目中,並與運行測試套件運行那麼它失敗java.lang.NoClassDefFoundError:組織/ TestNG的/ TestNG即使顯示完整路徑顯示testng.jar位於類路徑中。

因此,不知何故執行插件時使用的類路徑與我的項目中使用的類路徑不同,所以如何使插件依賴項出現在兩個地方?

回答

1

通過在使用該插件的項目中編譯時將TestNG直接添加到unmanagedJars,可以修復該錯誤。

在插件執行過程中,我還沒有找到解釋SBT類路徑結構的任何資源,所以任何試圖解釋爲什麼這一步都是必要的將不勝感激。

1

我會嘗試一個答案,但我不太熟悉sbt的內部細節。

正常情況下,構建系統的路徑(與您的程序相對)正在項目中進行,詳見here。那通常在project/plugins.sbt。聽起來是對的,因爲沒有理由說你開發的應用程序應該關心你的構建系統使用的庫,反之亦然。

當您的插件運行應用程序代碼時,可能不那麼簡單,並且可能存在classpath/classloader問題。我不確定它會起作用。通常,你的插件應該實現一個測試框架,而不是定義自己的任務。 Documentation of testing因爲sbt是有限的。

測試框架應執行org.scalatools.testing.Framework,在test-interface。您的版本將考慮這一點您添加

testFrameworks += new TestFramework("full.class.name") 

後,當你運行正常測試命令,它讓每一個框架,承認它與(可用兩個標準:繼承某些基類或有一些註釋)交易的測試類並運行它們。框架在構建中運行,它被賦予一個類加載器來訪問應用程序代碼。

你可以看看the framework implementation for junit(與sbt一起發貨)。還有一個TestNG implementation。根據它的文檔,我不知道它有點不正統,希望它能爲你工作。

+0

感謝您的澄清,不幸的是,testng測試界面不適用於我們的套件,這就是爲什麼我一起入侵一個小插件。我想避免實現一個完整的測試接口,而且我通常對在項目中運行時如何在類路徑中使用插件的依賴關係感到困惑。 –

+0

感謝您的幫助,我設法解決了我在問題答案中所描述的問題(儘管我不完全確定它的工作原理 - 這總是有點不盡人意)。 –