Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to attach custom task to execute before the test task in sbt?

I'm using SBT with Play Framework.

I created a custom TaskKey to run JavaScript tests in my project:

import sbt._
import sbt.Process._
import PlayProject._

object ApplicationBuild extends Build {

  val testJsTask = TaskKey[Unit]("testJs", "Run javascript tests.") := {}

  val main = PlayProject("xxx", 1.0, Seq())
    .settings(defaultScalaSettings: _*)
    .settings(testJsTask)
}

So far so good.

I want to run this testJsTask always when someone executes the test task.

I guess it should be something as follows:

test in Test <<= (test in Test).dependsOn(testJsTask)

I've no idea how it should be defined exactly. How to add a dependency to an existing task like 'test' or 'build'?

UPDATE

After changes proposed by @Christian the build definition looks as follows:

object ApplicationBuild extends Build {
  val testJsTask = TaskKey[Unit]("testJs", "Run tests for javascript client.")
  def testJs = {}

  val main = PlayProject("xxx", 1.0, Seq())
    .settings(defaultScalaSettings: _*)
    .settings(testJsTask := testJs)

  (test in Test) <<= (test in Test) dependsOn (testJs)
}

Unfortunately, the solution doesn't work either:

[error] /xxx/project/Build.scala:21: not found: value test
[error]   (test in Test) <<= (test in Test) dependsOn (testJs)
[error]    ^
[error] one error found
[error] {file:/xxx/project/}default-f468ae/compile:compile: Compilation failed
like image 429
Piotr Kukielka Avatar asked Dec 18 '11 21:12

Piotr Kukielka


People also ask

Can sbt execute tasks in parallel?

By default, sbt executes tasks in parallel (subject to the ordering constraints already described) in an effort to utilize all available processors. Also by default, each test class is mapped to its own task to enable executing tests in parallel.

How do I run a sbt task?

Run “sbt hello” from command line to invoke the task. Run “sbt tasks” to see this task listed.

Does sbt test compile?

We have a build. sbt file that is used for multiple projects. Doing sbt test:compile compiled the tests for every single project and took over 30 minutes.


2 Answers

This is one way to do it:

Define the task key:

val testJsTask = TaskKey[Unit]("testJs", "Run javascript tests.")    

Define the task in your projects settings:

testJsTask <<= testJs

Make test dependent on it:

(test in Test) <<= (test in Test) dependsOn (testJs)

testJs can be defined as follows:

  def testJs = (streams) map { (s) => {
    s.log.info("Executing task testJs")
    // Your implementation
  }

[EDIT] You have to define the task dependencies within the projects settings. For a "normal" project, you would do it the following way:

  lazy val testProject = Project(
    "testProject",
    file("testProject"),
    settings = defaultSettings ++ Seq(
      testJsTask <<= testJs,
      (test in Test) <<= (test in Test) dependsOn (testJsTask)
    )
  )
like image 128
Christian Avatar answered Oct 05 '22 23:10

Christian


Play 2.2.x uses SBT 0.13 (see What’s new in Play 2.2). That brings some new means of composing tasks in build.sbt itself (without resorting to a Scala file in project/ subdirectory).

If you happen to use Play 2.2.x you could define the dependency between the tasks in build.sbt as follows:

lazy val testJsTask = taskKey[Unit]("Run JavaScript tests.")

testJsTask := {
  println("Running JavaScript tests...")
  java.util.concurrent.TimeUnit.SECONDS.sleep(3)
  println("...done.")
}

test in Test := {
  testJsTask.value
  (test in Test).value
}

See Tasks in the official documentation of SBT for more details.

like image 43
Jacek Laskowski Avatar answered Oct 06 '22 00:10

Jacek Laskowski