37

I have a multi-project build with tests in sub-projects and in a parent project. The build is aggregated so that the parent project runs all tests in child projects.

I configured it so that there's no parallel execution of tests in both the sub-projects and the parent project, via

parallelExecution in Test := false

However, I have the nagging feeling that tests that span over multiple projects are ran in parallel. In the case of one of the sub-projects this is a problem because it mutates state in a test database concurrently, leading to the test to fail.

Any ideas as to how to globally switch of parallel execution of tests, between projects?

Manuel Bernhardt
  • 3,135
  • 2
  • 29
  • 36

7 Answers7

36

I think you can apply a setting across projects using scope ThisBuild, like

parallelExecution in ThisBuild := false

I don't know if you can combine that with scope Test, but it might not be necessary.

0__
  • 66,707
  • 21
  • 171
  • 266
23

To restrict the number of concurrently executing tests in all projects, use:

concurrentRestrictions in Global += Tags.limit(Tags.Test, 1)

See sbt documentation

See discussion

lisak
  • 21,611
  • 40
  • 152
  • 243
10

This worked for me in 1.1.0:

Test / parallelExecution := false

xmar
  • 1,729
  • 20
  • 48
4

See my answer here How to run subprojects tests (including setup methods) sequentially when testing

There is another way to prevent parallel execution. You can make the test tasks of the different projects depend on each other:

test in Project2 := (test in Project2).dependsOn(test in Project1).value
parallelExecution in Test in Project2 := false
Community
  • 1
  • 1
Boris Stumm
  • 120
  • 1
  • 3
  • 2
    This doesn't work for me: I am getting `References to undefined settings: Project2/*:test from Project2/*:test (/Users/the21st/Work/Project2/build.sbt:36) Did you mean Project2/web-assets-test:test ?` – the21st Jul 21 '15 at 09:34
2

The "modern" (i.e. sbt 1.x) equivalent of disabling parallel execution in Test scope is to add the following to your build.sbt:

Global / concurrentRestrictions += Tags.limit(Tags.Test, 1)

For those not familiar with sbt syntax, in context you want to do something like:

lazy val main = project
  .in(file("."))
  .settings(
    name := "foo",
    // more settings
    // ...
    Global / concurrentRestrictions += Tags.limit(Tags.Test, 1)
  )

From the tags and rules section of sbt docs.

p.s. quite a useful setting for ScalaTest, particularly around setup/teardown logic during database testing. Fixes some quite puzzling non-deterministic errors that you'll ineviitably hit with parallel execution enabled.

virtualeyes
  • 11,147
  • 6
  • 56
  • 91
  • 1
    This is the solution I was looking for but, interestingly, I did find that it only worked once I had removed the `Test / parallelExecution := false` rule from the sub-projects that were aggregated by the parent. – Andrew Kirk May 04 '23 at 20:55
1

Another possibility, based on https://stackoverflow.com/a/27068019/1922026, is to define a command alias in the root project:

.settings(addCommandAlias("test", ";s1/test;s2/test;s3/test"): _*)

where s1, s2 and s3 are the sub-projects. When you are in root project and run "test" the tests will be executed sequentially and in the order defined.

Community
  • 1
  • 1
1

You can try also Global / parallelExecution := false

Alex Elkin
  • 574
  • 6
  • 11