【问题标题】:Make tests in multi project sbt projects run only if tests pass in dependent projects仅当测试通过依赖项目时才运行多项目 sbt 项目中的测试
【发布时间】:2013-12-07 13:01:08
【问题描述】:

假设一个多项目 SBT 项目具有 foo-project 和 bar-project,这样 foo-project 依赖于 bar-project 的代码等。

如果 bar-project 中的测试通过,我希望 foo-project 中的测试运行。

怎么做?

【问题讨论】:

  • 为什么要避免运行这些?似乎 foo 测试依赖于 bar 实现(而不是 bar API),否则您可能不介意让它们运行。这不是你要解决的问题吗?
  • 我们遇到了两个问题:第一个是在多项目构建中某些测试可能会失败,但整体构建通过了,您不会注意到控制台上出现的故障。第二个是我们希望在运行耗时的浏览器测试之前运行单元测试。

标签: scala testing sbt


【解决方案1】:

您可以在项目之间提供明确的依赖关系。例如 root -> A -> B

Test case on GitHub。项目定义:

val commonSettings = Seq(libraryDependencies += "org.scalatest" %% "scalatest" % "1.9.1")

lazy val a: Project = (project in file("a")) settings(commonSettings: _*) settings(
    name := "a",
    test in Test <<= test in Test dependsOn (test in Test in b)
)

lazy val b: Project = (project in file("b")) settings(commonSettings: _*) settings(
    name := "b"
)

lazy val root: Project = (project in file(".")) settings(commonSettings: _*) settings(
    name := "root",
    test in Test <<= test in Test dependsOn (test in Test in a)
)

从B开始并成功完成:

ezh@mobile ZZZZZZ % sbt-0.13                                          
[info] Set current project to root (in build file:/home/ezh/ZZZZZZ/)
> root/test
[info] Compiling 1 Scala source to /home/ezh/ZZZZZZ/b/target/scala-2.10/test-classes...
[info] TestSpecB:
[info] This test 
[info] - should fail
[info] Passed: Total 1, Failed 0, Errors 0, Passed 1
[info] Compiling 1 Scala source to /home/ezh/ZZZZZZ/a/target/scala-2.10/test-classes...
[info] TestSpecA:
[info] This test 
[info] - should succeed
[info] Passed: Total 1, Failed 0, Errors 0, Passed 1
[info] Passed: Total 0, Failed 0, Errors 0, Passed 0
[info] No tests to run for root/test:test
[success] Total time: 5 s, completed 28.11.2013 16:20:12

从B开始但失败:

ezh@mobile ZZZZZZ % sbt-0.13                                          
[info] Set current project to root (in build file:/home/ezh/ZZZZZZ/)
> test
[info] Compiling 1 Scala source to /home/ezh/ZZZZZZ/b/target/scala-2.10/test-classes...
[info] TestSpecB:
[info] This test 
[info] - should fail *** FAILED ***
[info]   2 did not equal 3 (Test.scala:5)
[error] Failed: Total 1, Failed 1, Errors 0, Passed 0
[error] Failed tests:
[error]         TestSpecB
[error] (b/test:test) sbt.TestsFailedException: Tests unsuccessful
[error] Total time: 3 s, completed 28.11.2013 16:20:35
> 

【讨论】:

    【解决方案2】:

    正如已经指出的那样,这可能是邪恶的,但这应该可以工作:

    import sbt._
        import sbt.Keys._
        object Build extends Build {
          lazy val projectA = project
          lazy val myTest = taskKey[Seq[Option[Tests.Output]]]("my test")
          lazy val root: Project = project in file(".") settings (myTest <<= myTestTask) dependsOn projectA
    
          def myTestTask = Def.task {
            val state: State = Keys.state.value
            val log: Logger = streams.value.log
            val extracted = Project.extract(state)
            import extracted._
            def noTestsMessage(scoped: ScopedKey[_])(implicit display: Show[ScopedKey[_]]): String =
              "No tests to run for " + display(scoped)
            def f(ref: ProjectReference) = for {
              state Pair Value(r) <- Project.runTask(executeTests in(ref, Test), state)
              _ = Tests.showResults(log, r, noTestsMessage(test in ref))
            } yield r
            val depsTests = currentProject.dependencies.map(_.project).map(f)
            val passed = depsTests.forall(_.forall(_.overall == TestResult.Passed))
            if (passed) depsTests :+ f(ThisProject) else depsTests
          }
        }
    

    http://scastie.org/3319

    【讨论】:

      猜你喜欢
      • 2012-01-01
      • 2014-02-26
      • 1970-01-01
      • 2017-08-09
      • 2012-09-11
      • 2011-08-04
      • 2010-12-16
      相关资源
      最近更新 更多