我有一个SBT项目,它有一个完整的构建定义和用于测试的自定义配置。
我添加了一个自带配置的插件,如果可能的话,我希望能够使用两种配置来执行任务。
如果不可能,我想把配置从插件拉到我的自定义配置。
的细节我的自定义配置是unit
,它用于将某些测试分类为单元测试,并且我想使用sbt-scoverage添加覆盖率。
我的完整构建定义包括:
lazy val UnitTest = config("unit") extend(Test)
def unitTestFilter(name: String) = name endsWith "UnitSpec"
lazy val myProject = Project(id="MyProject")
.configs( UnitTest )
.settings( inConfig(UnitTest)(Defaults.testTasks) : _*)
.settings(
testOptions in UnitTest := Seq(Tests.Filter(unitTestFilter)),
parallelExecution in UnitTest := true
)
为了执行单元测试,我运行sbt unit:test
。
我如何A)将sbt-scoverage
添加到构建定义中的unit
配置,或者B)在SBT运行中包括scoverage
和unit
配置,例如sbt "unit,scoverage:test"
?
edit根据提供的2个答案,我正在接近我想要的。我现在遇到的问题是测试过滤器,并将其应用于配置。我已经更新了上面的原始代码片段,以包括我基于文件名使用的过滤器-参见项目部分中的testOptions
以及我如何使用unitTestFilter
。为了增加覆盖率,我添加了新的配置,用于覆盖率测试,所以现在有UnitTest
, ComponentTest
, CoverageUnitTest
和CoverageComponentTest
。我现在的问题是,我不能得到测试选项/文件名过滤器传播到scoverage配置。
lazy val CoverageUnitTest = config("coverUnit") extend (scoverageTest)
def unitTestFilter(name: String) = name endsWith "UnitSpec"
lazy val myProject = Project(id="MyProject")
.configs( UnitTest, CoverageUnitTest )
.settings(
testOptions in CoverageUnitTest := Seq(Tests.Filter(unitTestFilter)),
parallelExecution in CoverageUnitTest := true
)
在上述方法中,不应用设置。如果我运行coverUnit:test
,它执行组件和单元规格。我也尝试过使用testOptions in scoverageTest
,它与过滤器一起工作,但问题是我在我的项目中有2个配置,即CoverageUnitTest和CoverageComponentTest,如果我使用in scoverageTest
,那么只有1个过滤器适用于两个任务(即coverUnit:test和coverComponent:test都执行单元测试,或组件测试,基于顺序)。
方法2:扩展测试并增加仪器
lazy val CoverageUnitTest = config("coverUnit") extend (Test)
def unitTestFilter(name: String) = name endsWith "UnitSpec"
lazy val myProject = Project(id="MyProject")
.configs( UnitTest, CoverageUnitTest )
.settings( inConfig(CoverageUnitTest)(ScoverageSbtPlugin.instrumentSettings) : _* )
.settings(
testOptions in CoverageUnitTest := Seq(Tests.Filter(unitTestFilter)),
parallelExecution in CoverageUnitTest := true
)
同样,此方法不使用unitTestFilter过滤测试。
从查看ScoverageSbtPlugin源代码,看起来我可能需要以某种方式查看覆盖这: inConfig(scoverageTest)(Defaults.testSettings) ++
,这是正确的方法吗?
编辑# 2这里有一个变通方法,使用方法1,使用CoverageUnitTest"替换为"scoverageTest":
lazy val dynamicTestFilter(name:String):Boolean = name endsWith scala.util.Properties.envOrElse("TEST_TYPE","UnitSpec")
run with TEST_TYPE=ComponentSpec sbt coverComponent:test
我用sbt 0.13.5-M2 :
> about
[info] This is sbt 0.13.5-M2
[info] The current project is {file:/Users/jacek/sandbox/so/sbt-scoverage-custom-config/}myProject 0.1-SNAPSHOT
[info] The current project is built against Scala 2.10.4
[info] Available Plugins: sbt.plugins.IvyPlugin, sbt.plugins.JvmPlugin, sbt.plugins.CorePlugin, ScoverageSbtPlugin, scoverage.ScoverageSbtPlugin
[info] sbt, sbt plugins, and build definitions are using Scala 2.10.4
除非我弄错了,否则您正在询问将scoverage
设置应用于unit
,因此执行unit
的test
将与执行test:test
加scoverage
设置相同。如果是,请继续往下读。否则,请告知。
我认为,你应该在构建定义中有以下内容(我选择build.sbt
,这对我来说更简单):
scalaVersion := "2.10.4"
lazy val UnitTest = config("unit") extend(Test)
lazy val myProject = project
.in(file("."))
.configs(UnitTest)
.settings(
inConfig(UnitTest)(ScoverageSbtPlugin.instrumentSettings): _*
)
.settings(
parallelExecution in UnitTest := true
)
由于我对sbt-scoverage
几乎一无所知,所以除了验证设置外,我无法确认其正确配置:
> unit:libraryDependencies
[info] List(org.scala-lang:scala-library:2.10.4, org.scoverage:scalac-scoverage-plugin:0.97.0:scoverage)
> test:libraryDependencies
[info] List(org.scala-lang:scala-library:2.10.4)
我没有检查这个,但是你可以试试。
lazy val UnitTest = config("unit") extend(Test)
lazy val myProject = Project(id="MyProject").
configs(UnitTest, scoverage, scoverageTest).
settings(ScoverageSbtPlugin.instrumentSettings: _*).
settings(
parallelExecution in UnitTest := true,
sources in scoverageTest += (sources in UnitTest).value,
sourceDirectory in scoverageTest += (sourceDirectory in UnitTest).value,
unmanagedResources in scoverageTest += (unmanagedResources in UnitTest),
resourceDirectory in scoverageTest += (resourceDirectory in UnitTest),
externalDependencyClasspath in scoverageTest := Classpaths
.concat((externalDependencyClasspath in scoverageTest).value, (externalDependencyClasspath in UnitTest).value)
)
我将这两种建议结合起来使用,得出一个可行的配置。我使用了一个丑陋的hack,因为我不太确定如何停止配置继承,但这里或多或少是我所拥有的(我只展示了一个测试类型-单元-在这里,但我实际上有许多不同的类型。只有单元可以并行运行,组件/集成测试配置需要并行设置为false):
lazy val UnitTest = config("unit") extend(Test)
lazy val CoverageUnitTest = config("coverUnit") extend (scoverageTest)
def unitTestFilter(name: String) = name endsWith "UnitSpec"
def dynamicTestFilter(name:String): Boolean = name endsWith scala.util.Properties.envOrElse("TEST_TYPE","UnitSpec")
def determineParallel:Boolean = {
scala.util.Properties.envOrElse("TEST_TYPE","UnitSpec") match {
case testType:String if testType == "UnitSpec => true
case _ => false
}
}
lazy val myProject = Project(id="MyProject")
.configs( UnitTest, CoverageUnitTest )
.configs( ComponentTest, CoverageComponentTest )
.settings( inConfig(UnitTest)(Defaults.testTasks) : _*)
.settings(
testOptions in UnitTest := Seq(Tests.Filter(unitTestFilter)),
parallelExecution in UnitTest := true
)
.settings( inConfig(ComponentTest)(Defaults.testTasks) : _*)
.settings(
testOptions in ComponentTest := Seq(Tests.Filter(componentTestFilter)),
parallelExecution in ComponentTest := false
)
.settings(
testOptions in scoverageTest := Seq(Tests.Filter(unitTestFilter)),
parallelExecution in scoverageTest := determineParallel
)
第一组设置控制单元测试(无覆盖率),使用unit:test
执行,第二组设置控制组件测试(component:test
)。最后一个配置用于运行启用覆盖率的测试。scoverageTest配置用于单元和组件测试,但是我设置了一个系统属性,以便在运行SBT时使用一个标志来启用/禁用并行执行。
sbt coverUnit:test
将使用scoverageTest配置执行单元测试并启用并行。$ TEST_TYPE=ComponentSpec sbt coverComponent:test
在scoverageTest配置中执行组件测试,并通过determineParallel函数禁用并行执行。