How to configure ScalaTest to abort a test if the test fails?

I am using ScalaTest 2.1.4 with SBT 0.13.5. I have several long test suites that can take a long time if one test fails (tests with multiple Akka JVMs). I would like the whole package to be interrupted if any of them failed, otherwise the package can take a very long time, especially on our CI server.

How to configure ScalaTest to cancel dialing if any test in the package does not work?

+4
source share
2 answers

If you need to cancel only those tests from the same spec / suite / test test as with an error, you can use the CancelAfterFailure offset from scalatest. If you want to cancel them all over the world, here is an example:

import org.scalatest._


object CancelGloballyAfterFailure {
  @volatile var cancelRemaining = false
}

trait CancelGloballyAfterFailure extends SuiteMixin { this: Suite =>
  import CancelGloballyAfterFailure._

  abstract override def withFixture(test: NoArgTest): Outcome = {
    if (cancelRemaining)
      Canceled("Canceled by CancelGloballyAfterFailure because a test failed previously")
    else
      super.withFixture(test) match {
        case failed: Failed =>
          cancelRemaining = true
          failed
        case outcome => outcome
      }
  }

  final def newInstance: Suite with OneInstancePerTest = throw new UnsupportedOperationException
}

class Suite1 extends FlatSpec with CancelGloballyAfterFailure {

  "Suite1" should "fail in first test" in {
    println("Suite1 First Test!")
    assert(false)
  }

  it should "skip second test" in {
    println("Suite1 Second Test!")
  }

}

class Suite2 extends FlatSpec with CancelGloballyAfterFailure {

  "Suite2" should "skip first test" in {
    println("Suite2 First Test!")
  }

  it should "skip second test" in {
    println("Suite2 Second Test!")
  }

}
+4
source

Thanks, Eugene; here is my improvement:

trait TestBase extends FunSuite {
  import TestBase._

  override def withFixture(test: NoArgTest): Outcome = {
    if (aborted) Canceled(s"Canceled because $explanation")
    else super.withFixture(test)
  }

  def abort(text: String = "one of the tests failed"): Unit = {
    aborted = true
    explanation = text
  }
}

object TestBase {
  @volatile var aborted = false
  @volatile var explanation = "nothing happened"
}

I wonder if this can be done without using vars.

0
source

All Articles