1

我有一个 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.

IA)将如何添加到构建定义中sbt-scoverage的配置中,或者 B)如何在 SBT 运行中同时包含和配置,例如?unitscoverageunitsbt "unit,scoverage:test"

编辑根据提供的 2 个答案,我正在接近我想要的。我现在遇到的问题是测试过滤器,并将其应用于配置。我已经更新了上面的原始代码片段,以包含我使用的基于文件名的过滤器 - 请参阅testOptions项目部分以及我的使用方式unitTestFilter。为了增加覆盖率,我为覆盖率测试添加了新配置,所以现在有了UnitTestComponentTest和. 我现在遇到的问题是我无法让测试选项/文件名过滤器传播到覆盖配置。CoverageUnitTestCoverageComponentTest

方法 1:创建一个扩展 scoverageTest 的配置

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,它会执行组件和单元规范。我也尝试过 using 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 源,看起来我可能需要以某种方式考虑覆盖 this: inConfig(scoverageTest)(Defaults.testSettings) ++,这是正确的方法吗?

编辑 #2 这是一个变通方法,使用方法 1,将“CoverageUnitTest”替换为“scoverageTest”:

lazy val dynamicTestFilter(name:String):Boolean = name endsWith scala.util.Properties.envOrElse("TEST_TYPE","UnitSpec")

运行TEST_TYPE=ComponentSpec sbt coverComponent:test

4

3 回答 3

1

我使用 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'stest将与执行test:testscoverage设置相同。如果是这样,请继续阅读。否则请指教。

我认为,您应该在构建定义中包含以下内容(我选择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)
于 2014-03-29T14:55:44.493 回答
1

我没有检查这个,但这里有一些你可以尝试的东西。

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)
  )
于 2014-03-29T22:12:51.540 回答
0

我结合使用这两种建议来提出一个有效的配置。我使用了 1 个丑陋的 hack,因为我不太确定如何停止配置继承,但这或多或少是我所拥有的(我只显示 1 种测试类型 - 单元 - 这里,但我实际上有许多不同的类型. 只有单元可以并行运行,组件/集成测试配置需要并行设置为 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 函数禁用并行执行。

于 2014-05-09T13:16:26.593 回答