SBT:覆盖任务“test”的行为以仅从默认 testSource 文件夹运行测试,有多个测试源文件夹

Posted

技术标签:

【中文标题】SBT:覆盖任务“test”的行为以仅从默认 testSource 文件夹运行测试,有多个测试源文件夹【英文标题】:SBT : Override behavior of task "test" to run only tests from default testSource folder, there are multiple test source folders 【发布时间】:2018-02-17 15:38:51 【问题描述】:

我们有标准目录结构的标准 SBT 项目。

test 文件夹包含所有 JUnit 测试。

我们引入了一个新文件夹 othertests 并且文件夹 othertests 是对等文件夹 测试

othertest 文件夹包含一些特殊的测试用例。 othertest 文件夹中的测试类名称可以很容易地与普通的 JUnit 测试区分开来。

下面是我的工作 build.sbt 配置。

我使用javaSources in Test SBT 任务在测试源中添加了文件夹othertest

我们正在使用 activator 来运行测试和做其他事情。

当我运行 activator> test 时,我只想运行文件夹 test 中的所有测试,并且我想运行文件夹 othertests 中的测试 分开。

问题。

    如何覆盖测试任务的行为以从文件夹 othertests 中过滤掉测试 我是否应该创建共享模块来分别运行普通的 junit 测试和其他的 junit 测试。

下面是我的 build.sbt 配置

import java.io.PrintStream

import play.sbt.PlayJava
import play.twirl.sbt.Import._

name := "Service"

version := "5.1.0"

scalaVersion := "2.11.8"

routesGenerator := InjectedRoutesGenerator

lazy val ContractTest = config("contract") extend(Test)

def contractTestFilter(name: String): Boolean = name endsWith "ContractTest"

def ignoreContractTest(name: String): Boolean = !contractTestFilter(name)

lazy val root = (project in file("."))
  .enablePlugins(PlayJava)
  .configs(ContractTest)
    .settings(
      inConfig(ContractTest) (Defaults.testTasks),
      javaSource in Test :=  (baseDirectory in Test) (_ / "contracttest") .value,
      testOptions in ContractTest := Seq(Tests.Filter(contractTestFilter),Tests.Argument(TestFrameworks.JUnit, "-q", "-v", "-s")),
      testOptions in Test := Seq(Tests.Filter(ignoreContractTest),Tests.Argument(TestFrameworks.JUnit, "-q", "-v", "-s"))
    )

lazy val xyz = taskKey[Unit]("custom task to create loglayout jar file under lib folder")

xyz := 
  LogLayoutJar.build(scalaBinaryVersion.value, streams.value.log)


run := (run in Runtime).dependsOn(xyz).evaluated

javaOptions in Test ++= Seq("-Dconfig.resource=applic.tt.cnf")

libraryDependencies ++= Seq(
  json,
  javaWs,
  "org.mockito" % "mockito-all" % "1.10.19" % Test,
  "org.scalatestplus.play" %% "scalatestplus-play" % "1.5.1" % Test,
  "org.easytesting" % "fest-assert" % "1.4" % Test,
  "org.scalactic" %% "scalactic" % "2.2.0",
  "org.jmockit" % "jmockit" % "1.9" % Test,
  "com.portingle" % "slf4jtesting" % "1.0.0" % Test,
  "org.scalacheck" %% "scalacheck" % "1.12.6" % Test
)

resolvers ++= Seq(
  "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/"
)

parallelExecution in Test := runningTestInParallel

testGrouping in Test := groupByModule((externalDependencyClasspath in Test).value,
  (definedTests in Test).value, streams.value.log)

javacOptions ++= Seq(
  "-Xlint:unchecked",
  "-Xlint:deprecation"
)
scalacOptions ++= Seq(
  "-feature",
  "-language:implicitConversions",
  "-deprecation"
)

// Custom tasks //
val silenceSystemErr = taskKey[Unit]("Replaces System.err with a PrintStream to nowhere.")

silenceSystemErr := 
  System.setErr(new PrintStream(new DevNull))
  println("Messages System.err will not be printed.")


val restoreSystemErr = taskKey[Unit]("Restores the original System.err")

restoreSystemErr := 
  System.setErr(systemErr)
  println("Messages System.err will be printed.")

我们在 jenkins 中使用以下命令运行测试 -

bin/activator -Dsbt.log.noformat=true -Denvironment_name=test -DsuppressLogging=true clean silenceSystemErr jacoco:cover

谢谢你 拉克什

【问题讨论】:

【参考方案1】:

1.

你自相矛盾。在运行Test 命令时,如果不想让它们运行,为什么要添加javaSources in Test

您应该做的是创建一个 [Additional Test configuration|http://www.scala-sbt.org/0.13/docs/Testing.html#Additional+test+configurations] 扩展 Test 并仅在您的 othertests 文件夹中运行测试。

2.

您可以创建另一个模块。我个人不喜欢这个想法,因为我必须根据模块的测试来命名模块,而且我有 2 个单独的模块,实际上应该只有一个。

如果您的测试中有一些依赖项会减慢模块的整体构建时间,那么单独的测试模块可能是一个好主意。例如,想象一个带有 Gatling 性能测试的 Java 项目。如果性能测试在同一个模块中,那么每当我rebuild 它也会rebuild 需要更慢的 scala 编译器的加特林测试。

有些人可以忍受这一点,我就是其中之一。我更喜欢在同一个项目中进行测试,并且在重建模块时可能会遭受时间损失。这种情况很少发生,我会在需要时创建不同的测试配置。

为测试选择单独模块的另一个原因是,当您的测试依赖于多个模块并且您不希望在 src 代码的编译时出现此模块依赖关系。

某些 IDE 和/或语言可能会鼓励使用单独的模块进行测试,因为我理解 C# 和 Visual Studio 就是这种情况(但我在这里可能错了,不要相信我的话)。

【讨论】:

谢谢@pedromss。您的建议很有用,我能够实现我想要的。我正在分享我的配置,因此对其他人也很有用。我能够创建自定义测试配置并能够过滤所有必需的测试。但是,在配置更改后,我看到了 jenkins 构建中生成的日志的 1 个副作用。您能否帮助解释为什么会生成额外的日志。我的 build.sbt 文件配置在下面的新评论中给出。 我已经编辑了我的问题以添加工作 build.sbt 文件。 我在 jenkins 日志中看到的一个不同的日志是 - [DEBUG] [09/12/2017 03:02:52.467] [application-akka.actor.default-dispatcher-2] [EventStream] shutting down: StandardOutLogger started。它说StandardOutLogger 开始了。这可能是我看到所有不必要的日志的原因吗? 看到您的日志来自 akka,我会说它与 sbt 无关。查看 akka 文档以了解如何调整日志或降低日志级别

以上是关于SBT:覆盖任务“test”的行为以仅从默认 testSource 文件夹运行测试,有多个测试源文件夹的主要内容,如果未能解决你的问题,请参考以下文章

聚合 SQL 函数以仅从每个组中获取第一个

使用 activerecord 发出请求以仅从组中获取用户,而不从其他人中获取

配置 SBT 以仅解析 Ivy 存储库中的 jar(而不是 war)

Pyspark:加入 2 个数据帧以仅从第 2 个数据帧获取新记录(历史化)

覆盖 SBT 插件中的映射

SBT:多构建依赖/聚合项目中的覆盖设置