2011-10-26 84 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

感谢您的帮助,我设法解决了我在问题答案中所描述的问题(尽管我不完全确定它的工作原理 - 这总是有点不尽人意)。 –