【问题标题】:Why are integration tests in a Play/Scala project not executed when using "sbt it:test"?为什么在使用“sbt it:test”时不执行 Play/Scala 项目中的集成测试?
【发布时间】:2014-11-07 05:08:32
【问题描述】:

我有一个Play Framework 2.3 项目,我想将单元测试和功能测试分开如下:

  1. 运行 sbt test 应该运行单元测试并排除集成测试
  2. 运行 sbt it:test 应该只运行集成测试

Scala 文档建议使用project/Build.scala,但我想使用build.sbtproject/Build.scala 的组合,所以我的配置看起来像这样(我也尝试将所有配置放入Build.scala):

build.sbt

....

libraryDependencies ++= Seq(
  "com.typesafe.play" %% "play-json" % "2.2.3",
  "org.scalatest" %% "scalatest" % "2.1.5" % "it, test",
  "org.mockito" % "mockito-all" % "1.9.5" % "it, test"
)

def funTestFilter(name: String): Boolean = ((name endsWith "ItTest") || (name endsWith "IntegrationTest"))
def unitTestFilter(name: String): Boolean = ((name endsWith "Test") && !funTestFilter(name))

testOptions in IntegrationTest := Seq(Tests.Filter(funTestFilter))

testOptions in Test := Seq(Tests.Filter(unitTestFilter))

project/Build.scala

import sbt._

object Build extends Build {

  lazy val root =
    Project("root", file("."))
      .configs( IntegrationTest )
      .settings( Defaults.itSettings : _* )

}

在此配置下运行 sbt test 确实排除了我的集成测试(以 IntegrationTest 结尾)但运行 sbt it:test 找不到任何测试。

文章建议将文件放在特定路径中,但我不知道 Play 项目的等效路径是什么。

使用标准源层次结构:

src/it/scala for Scala sources
src/it/java for Java sources
src/it/resources for resources that should go on the integration test classpath

【问题讨论】:

    标签: scala sbt playframework-2.3


    【解决方案1】:

    第一部分——关于在build.sbt 中设置集成测试——在另一个问题What would be the minimal setup of IntegrationTest configuration in sbt 0.13.x? 中进行了描述——它归结为build.sbt 中的以下条目:

    Defaults.itSettings
    
    lazy val root = project.in(file(".")).configs(IntegrationTest)
    

    由于一个 Play 项目的定义如下:

    lazy val root = (project in file(".")).enablePlugins(PlayScala)
    

    你应该添加configs,你就完成了。

    lazy val root = project in file(".") enablePlugins(PlayScala) configs(IntegrationTest) 
    

    执行reload 或重新启动sbt/activator 会话并执行it:test

    [it-play] $ it:test
    [info] Updating {file:/Users/jacek/sandbox/it-play/}root...
    [info] Resolving jline#jline;2.11 ...
    [info] Done updating.
    [success] Total time: 1 s, completed Sep 13, 2014 7:12:27 PM
    

    关于集成测试在 Play 项目中的位置,简短的回答是在 shell 中执行show it:sourceDirectory,即src/itscalajavaresources 目录下包含各自的来源。

    it 配置中添加测试框架库,即在build.sbt 中应该有类似的东西 - 注意it 配置:

    "org.specs2" %% "specs2" % "2.4.2" % "it"
    

    执行reload sbt 会话或重新启动它,it:test 应该适用于 src/it/scala 下的所有测试的 Specs2 测试。

    要缩小应执行的测试范围,请添加您的过滤器 - 确保它位于 Defaults.itSettings 行之后,因为顺序很重要,并且可以覆盖另一个:

    val funTestFilter: String => Boolean = { name =>
      (name endsWith "ItTest") || (name endsWith "IntegrationTest")
    }
    
    testOptions in IntegrationTest += Tests.Filter(funTestFilter)
    

    执行reload 或重启sbt 并执行it:test。它应该工作。执行show it:testOptions 以确保您的设置正确加载:

    [it-play] $ show it:testOptions
    [info] List(Filter(<function1>))
    

    为我工作的整个build.sbt 如下 - 它是由activator new it-play play-scala 创建的:

    name := """it-play"""
    
    version := "1.0-SNAPSHOT"
    
    lazy val root = project in file(".") enablePlugins(PlayScala) configs(IntegrationTest)
    
    scalaVersion := "2.11.1"
    
    libraryDependencies ++= Seq(
      jdbc,
      anorm,
      cache,
      ws,
      "org.specs2" %% "specs2" % "2.4.2" % "it"
    )
    
    Defaults.itSettings
    
    val funTestFilter: String => Boolean = { name =>
      (name endsWith "ItTest") || (name endsWith "IntegrationTest")
    }
    
    testOptions in IntegrationTest += Tests.Filter(funTestFilter)
    

    【讨论】:

    • 谢谢!!!。我的项目不知道“PlayScala”是什么,这是我得到的错误:“/web/api-checkout/build.sbt:28: error: not found: value PlayScala”,但是,没有它似乎可以工作, 不知道不然会导致什么问题,暂时还没有发现问题。
    • 使用 Play 2.3.9,我按照示例进行操作,但我的 IntegrationSpec.scala 无法编译,因为它找不到 PlaySpecification 即类 IntegrationSpec 扩展 PlaySpecification。知道为什么 SBT 没有在“它”阶段包含播放库吗?另外,我已将此添加到 build.sbt, "org.specs2" %% "specs2-core" % "3.5" % "it, test", "org.specs2" %% "specs2-junit" % "3.5" % "it, test", "org.specs2" %% "specs2-mock" % "3.5" % "it, test" 谢谢
    • 好的,我在 "it" 中添加了 play-test,即 "com.typesafe.play" %% "play-test" % "2.3.9" % "it"
    • 令人困惑的是,Play 的集成测试是“src/it”而不是“/it”,因为如果它在基本目录中的“/app”和“/test”旁边会更有意义,根据the Play Anatomy。我通过将build.sbt 中的设置更改为sourceDirectory in IntegrationTest := baseDirectory.value / "it",将我的集成测试移到了那里。然后它会找到通常的it/javait/scalait/resources 目录。
    • 这是一个很奇怪的命名建议——在不区分大小写的情况下,UnitTest 也以ItTest 结尾,而事实上ItTest 解析为IntegrationTestTest ;-)
    【解决方案2】:

    这就是我最终做的事情,这让我能够:

    1. 将我的集成测试保存在 play 的 /test 目录中
    2. 运行sbt test 进行单元测试,运行sbt fun:test 进行功能/集成测试

    这里是build.sbt,不需要project/Build.scala

    libraryDependencies ++= Seq(
      ...
      "com.typesafe.play" %% "play-json" % "2.2.3",
      "org.scalatest" %% "scalatest" % "2.1.5" % "test",
      "org.mockito" % "mockito-all" % "1.9.5" % "test"
    )
    
    lazy val FunTest = config("fun") extend(Test)
    
    def funTestFilter(name: String): Boolean = ((name endsWith "ItTest") || (name endsWith "IntegrationTest"))
    def unitTestFilter(name: String): Boolean = ((name endsWith "Test") && !funTestFilter(name))
    
    lazy val root = project in file(".") configs(FunTest) settings( inConfig(FunTest)(Defaults.testTasks) : _*)
    
    testOptions in FunTest := Seq(Tests.Filter(funTestFilter))
    
    testOptions in Test := Seq(Tests.Filter(unitTestFilter))
    

    【讨论】:

    • 我真的很喜欢这个解决方案,因为我可以克隆并进入任何选择的 IDE。如果我创建一个新的测试文件夹,那么从今天开始,我必须将 IDE 特定的东西放入我的构建(ick)中,或者有一个额外的 IDE 步骤来告诉 IDE 我的新文件夹(也不是很好)。
    猜你喜欢
    • 1970-01-01
    • 2023-03-12
    • 2014-06-16
    • 1970-01-01
    • 2020-02-21
    • 2022-01-08
    • 1970-01-01
    • 2019-12-24
    • 1970-01-01
    相关资源
    最近更新 更多