Выполнять тесты в проектах нескольких проектов sbt, только если тесты проходят в зависимых проектах

Предполагая мультипроектный SBT-проект с проектом foo-project и bar-project, так что foo-проект зависит от bar-проекта для кода и т.д.

Мне бы хотелось, чтобы тесты в foo-project выполнялись, если тесты проходили через bar-project pass.

Как?

Ответ 1

Вы можете предоставлять явные зависимости между проектами. Например, root → A → B

Тест-сценарий на 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 и успешно завершая их:

[email protected] 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, но сбой:

[email protected] 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