Package

org.scalatest

concurrent

Permalink

package concurrent

Visibility
  1. Public
  2. All

Type Members

  1. trait AbstractPatienceConfiguration extends ScaledTimeSpans

    Permalink

    Trait that defines an abstract patienceConfig method that is implemented in PatienceConfiguration and can be overriden in stackable modification traits such as IntegrationPatience.

    Trait that defines an abstract patienceConfig method that is implemented in PatienceConfiguration and can be overriden in stackable modification traits such as IntegrationPatience.

    The main purpose of AbstractPatienceConfiguration is to differentiate core PatienceConfiguration traits, such as Eventually and AsyncAssertions, from stackable modification traits for PatienceConfigurations such as IntegrationPatience. Because these stackable traits extend AbstractPatienceConfiguration instead of Suite, you can't simply mix in a stackable trait:

    class ExampleSpec extends FunSpec with IntegrationPatience // Won't compile
    

    The previous code is undesirable because IntegrationPatience would have no affect on the class. Instead, you need to mix in a core PatienceConfiguration trait and mix the stackable IntegrationPatience trait into that, like this:

    class ExampleSpec extends FunSpec with Eventually with IntegrationPatience // Compiles fine
    

    The previous code is better because IntegrationPatience does have an effect: it modifies the behavior of Eventually.

  2. trait Futures extends PatienceConfiguration

    Permalink

    Trait that facilitates testing with futures.

    Trait that facilitates testing with futures.

    This trait defines a FutureConcept trait that can be used to implicitly wrap different kinds of futures, thereby providing a uniform testing API for futures. The three ways this trait enables you to test futures are:

    1. Invoking isReadyWithin, to assert that a future is ready within a a specified time period. Here's an example:

    assert(result.isReadyWithin(100 millis))
    

    2. Invoking futureValue, to obtain a futures result within a specified or implicit time period, like this:

    assert(result.futureValue === 7)
    

    3. Passing the future to whenReady, and performing assertions on the result value passed to the given function, as in:

    whenReady(result) { s =>
      s should be ("hello")
    }
    

    The whenReady construct periodically inspects the passed future, until it is either ready or the configured timeout has been surpassed. If the future becomes ready before the timeout, whenReady passes the future's value to the specified function.

    To make whenReady more broadly applicable, the type of future it accepts is a FutureConcept[T], where T is the type of value promised by the future. Passing a future to whenReady requires an implicit conversion from the type of future you wish to pass (the modeled type) to FutureConcept[T]. Subtrait JavaFutures provides an implicit conversion from java.util.concurrent.Future[T] to FutureConcept[T].

    For example, the following invocation of whenReady would succeed (not throw an exception):

    import org.scalatest._
    import matchers.ShouldMatchers._
    import concurrent.Futures._
    import java.util.concurrent._
    
    val exec = Executors.newSingleThreadExecutor
    val task = new Callable[String] { def call() = { Thread.sleep(50); "hi" } }
    whenReady(exec.submit(task)) { s =>
      s should be ("hi")
    }
    

    However, because the default timeout is 150 milliseconds, the following invocation of whenReady would ultimately produce a TestFailedException:

    val task = new Callable[String] { def call() = { Thread.sleep(500); "hi" } }
    whenReady(exec.submit(task)) { s =>
      s should be ("hi")
    }
    

    Assuming the default configuration parameters, a timeout of 150 milliseconds and an interval of 15 milliseconds, were passed implicitly to whenReady, the detail message of the thrown TestFailedException would look like:

    The future passed to whenReady was never ready, so whenReady timed out. Queried 95 times, sleeping 10 milliseconds between each query.

    Configuration of whenReady

    The whenReady methods of this trait can be flexibly configured. The two configuration parameters for whenReady along with their default values and meanings are described in the following table:

    Configuration Parameter Default Value Meaning
    timeout scaled(150 milliseconds) the maximum amount of time to allow unsuccessful queries before giving up and throwing TestFailedException
    interval scaled(15 milliseconds) the amount of time to sleep between each query

    The default values of both timeout and interval are passed to the scaled method, inherited from ScaledTimeSpans, so that the defaults can be scaled up or down together with other scaled time spans. See the documentation for trait ScaledTimeSpans for more information.

    The whenReady methods of trait Futures each take a PatienceConfig object as an implicit parameter. This object provides values for the two configuration parameters. Trait Futures provides an implicit val named defaultPatience with each configuration parameter set to its default value. If you want to set one or more configuration parameters to a different value for all invocations of whenReady in a suite you can override this val (or hide it, for example, if you are importing the members of the Futures companion object rather than mixing in the trait). For example, if you always want the default timeout to be 2 seconds and the default interval to be 5 milliseconds, you can override defaultPatience, like this:

    implicit override val defaultPatience =
      PatienceConfig(timeout = Span(2, Seconds), interval = Span(5, Millis))
    

    Or, hide it by declaring a variable of the same name in whatever scope you want the changed values to be in effect:

    implicit val defaultPatience =
      PatienceConfig(timeout =  Span(2, Seconds), interval = Span(5, Millis))
    

    In addition to taking a PatienceConfig object as an implicit parameter, the whenReady methods of trait Futures include overloaded forms that take one or two PatienceConfigParam objects that you can use to override the values provided by the implicit PatienceConfig for a single whenReady invocation. For example, if you want to set timeout to 6 seconds for just one particular whenReady invocation, you can do so like this:

    whenReady (exec.submit(task), timeout(Span(6, Seconds))) { s =>
      s should be ("hi")
    }
    

    This invocation of eventually will use 6000 for timeout and whatever value is specified by the implicitly passed PatienceConfig object for the interval configuration parameter. If you want to set both configuration parameters in this way, just list them separated by commas:

    whenReady (exec.submit(task), timeout(Span(6, Seconds)), interval(Span(500, Millis))) { s =>
      s should be ("hi")
    }
    

    You can also import or mix in the members of SpanSugar if you want a more concise DSL for expressing time spans:

    whenReady (exec.submit(task), timeout(6 seconds), interval(500 millis)) { s =>
      s should be ("hi")
    }
    

    Note: The whenReady construct was in part inspired by the whenDelivered matcher of the BlueEyes project, a lightweight, asynchronous web framework for Scala.

  3. trait IntegrationPatience extends AbstractPatienceConfiguration

    Permalink

    Stackable modification trait for PatienceConfiguration that provides default timeout and interval values appropriate for integration testing.

    Stackable modification trait for PatienceConfiguration that provides default timeout and interval values appropriate for integration testing.

    The default values for the parameters are:

    Configuration ParameterDefault Value
    timeout scaled(15 seconds)
    interval scaled(150 milliseconds)

    The default values of both timeout and interval are passed to the scaled method, inherited from ScaledTimeSpans, so that the defaults can be scaled up or down together with other scaled time spans. See the documentation for trait ScaledTimeSpans for more information.

    Mix this trait into any class that uses PatienceConfiguration (such as classes that mix in Eventually or AsyncAssertions) to get timeouts tuned towards integration testing, like this:

    class ExampleSpec extends FeatureSpec with Eventually with IntegrationPatience {
      // ...
    }
    

  4. trait PatienceConfiguration extends AbstractPatienceConfiguration

    Permalink

    Trait providing methods and classes used to configure timeouts and, where relevant, the interval between retries.

    Trait providing methods and classes used to configure timeouts and, where relevant, the interval between retries.

    This trait is called PatienceConfiguration because it allows configuration of two values related to patience: The timeout specifies how much time asynchronous operations will be given to succeed before giving up. The interval specifies how much time to wait between checks to determine success when polling.

    The default values for timeout and interval provided by trait PatienceConfiguration are tuned for unit testing, where running tests as fast as possible is a high priority and subsystems requiring asynchronous operations are therefore often replaced by mocks. This table shows the default values:

    Configuration ParameterDefault Value
    timeout scaled(150 milliseconds)
    interval scaled(15 milliseconds)

    Values more appropriate to integration testing, where asynchronous operations tend to take longer because the tests are run against the actual subsytems (not mocks), can be obtained by mixing in trait IntegrationPatience.

    The default values of both timeout and interval are passed to the scaled method, inherited from ScaledTimeSpans, so that the defaults can be scaled up or down together with other scaled time spans. See the documentation for trait ScaledTimeSpans for more information.

    Timeouts are used by the eventually methods of trait Eventually and the await method of class Waiter, a member of trait AsyncAssertions. Intervals are used by the eventually methods.

  5. trait ScalaFutures extends Futures

    Permalink

    Provides an implicit conversion from scala.concurrent.Future[T] to FutureConcept[T].

    Provides an implicit conversion from scala.concurrent.Future[T] to FutureConcept[T].

    This trait enables you to invoke the methods defined on FutureConcept on a Scala Future, as well as to pass a Scala future to the whenReady methods of supertrait Futures. See the documentation for supertrait Futures for the details on the syntax this trait provides for testing with Scala futures.

  6. trait ScaledTimeSpans extends AnyRef

    Permalink

    Trait providing a scaled method that can be used to scale time Spans used during the testing of asynchronous operations.

    Trait providing a scaled method that can be used to scale time Spans used during the testing of asynchronous operations.

    The scaled method allows tests of asynchronous operations to be tuned according to need. For example, Spans can be scaled larger when running tests on slower continuous integration servers or smaller when running on faster development machines.

    The Double factor by which to scale the Spans passed to scaled is obtained from the spanScaleFactor method, also declared in this trait. By default this method returns 1.0, but can be configured to return a different value by passing a -F argument to Runner (or an equivalent mechanism in an ant, sbt, or Maven build file).

    The default timeouts and intervals defined for traits Eventually and AsyncAssertions invoke scaled, so those defaults will be scaled automatically. Other than such defaults, however, to get a Span to scale you'll need to explicitly pass it to scaled. For example, here's how you would scale a Span you supply to the failAfter method from trait Timeouts:

    failAfter(scaled(150 millis)) {
      // ...
    }
    

    The reason Spans are not scaled automatically in the general case is to make code obvious. If a reader sees failAfter(1 second), it will mean exactly that: fail after one second. And if a Span will be scaled, the reader will clearly see that as well: failAfter(scaled(1 second)).

    Overriding spanScaleFactor

    You can override the spanScaleFactor method to configure the factor by a different means. For example, to configure the factor from Akka TestKit's test time factor you might create a trait like this:

    import org.scalatest.concurrent.ScaledTimeSpans
    import akka.actor.ActorSystem
    import akka.testkit.TestKitExtension
    
    trait AkkaSpanScaleFactor extends ScaledTimeSpans {
      override def spanScaleFactor: Double =
          TestKitExtension.get(ActorSystem()).TestTimeFactor
    }
    

    This trait overrides spanScaleFactor so that it takes its scale factor from Akka's application.conf file. You could then scale Spans tenfold in Akka's configuration file like this:

    akka {
      test {
        timefactor = 10.0
      }
    }
    

    Armed with this trait and configuration file, you can simply mix trait AkkaSpanScaleFactor into any test class whose Spans you want to scale, like this:

    class MySpec extends FunSpec with Eventually with AkkaSpanScaleFactor {
      // ..
    }
    

Value Members

  1. object PatienceConfiguration

    Permalink
  2. object ScalaFutures extends ScalaFutures

    Permalink

    Companion object that facilitates the importing of ScalaFutures members as an alternative to mixing in the trait.

    Companion object that facilitates the importing of ScalaFutures members as an alternative to mixing in the trait. One use case is to import ScalaFutures's members so you can use them in the Scala interpreter.

Ungrouped