Commands

trait Commands

An API for stateful testing in ScalaCheck.

An API for stateful testing in ScalaCheck.

For an implementation overview, see the examples in ScalaCheck's source tree.

Since

1.12.0

class Object
trait Matchable
class Any

Type members

Classlikes

trait Command

A type representing the commands that can run in the system under test. This type should be immutable and implement the equality operator properly.

A type representing the commands that can run in the system under test. This type should be immutable and implement the equality operator properly.

case object NoOp extends Command

A command that doesn't do anything

A command that doesn't do anything

trait SuccessCommand extends Command

A command that never should throw an exception on execution.

A command that never should throw an exception on execution.

trait UnitCommand extends Command

A command that doesn't return a result, only succeeds or fails.

A command that doesn't return a result, only succeeds or fails.

Types

type State

The abstract state type. Must be immutable. The State type should model the state of the system under test (SUT). It should only contain details needed for specifying our pre- and post-conditions, and for creating Sut instances.

The abstract state type. Must be immutable. The State type should model the state of the system under test (SUT). It should only contain details needed for specifying our pre- and post-conditions, and for creating Sut instances.

type Sut

A type representing one instance of the system under test (SUT). The Sut type should be a proxy to the actual system under test and is therefore, by definition, a mutable type. It is used by the Command.run method to execute commands in the system under test. It should be possible to have any number of co-existing instances of the Sut type, as long as canCreateNewSut isn't violated, and each Sut instance should be a proxy to a distinct SUT instance. There should be no dependencies between the Sut instances, as they might be used in parallel by ScalaCheck. Sut instances are created by newSut and destroyed by destroySut. newSut and destroySut might be called at any time by ScalaCheck, as long as canCreateNewSut isn't violated.

A type representing one instance of the system under test (SUT). The Sut type should be a proxy to the actual system under test and is therefore, by definition, a mutable type. It is used by the Command.run method to execute commands in the system under test. It should be possible to have any number of co-existing instances of the Sut type, as long as canCreateNewSut isn't violated, and each Sut instance should be a proxy to a distinct SUT instance. There should be no dependencies between the Sut instances, as they might be used in parallel by ScalaCheck. Sut instances are created by newSut and destroyed by destroySut. newSut and destroySut might be called at any time by ScalaCheck, as long as canCreateNewSut isn't violated.

Value members

Abstract methods

def canCreateNewSut(newState: State, initSuts: Iterable[State], runningSuts: Iterable[Sut]): Boolean

Decides if newSut should be allowed to be called with the specified state instance. This can be used to limit the number of co-existing Sut instances. The list of existing states represents the initial states (not the current states) for all Sut instances that are active for the moment. If this method is implemented incorrectly, for example if it returns false even if the list of existing states is empty, ScalaCheck might hang.

Decides if newSut should be allowed to be called with the specified state instance. This can be used to limit the number of co-existing Sut instances. The list of existing states represents the initial states (not the current states) for all Sut instances that are active for the moment. If this method is implemented incorrectly, for example if it returns false even if the list of existing states is empty, ScalaCheck might hang.

If you want to allow only one Sut instance to exist at any given time (a singleton Sut), implement this method the following way:

def canCreateNewSut(newState: State, initSuts: Traversable[State]
  runningSuts: Traversable[Sut]
) = {
  initSuts.isEmpty && runningSuts.isEmpty
}
def destroySut(sut: Sut): Unit

Destroy the system represented by the given Sut instance, and release any resources related to it.

Destroy the system represented by the given Sut instance, and release any resources related to it.

def genCommand(state: State): Gen[Command]

A generator that, given the current abstract state, should produce a suitable Command instance.

A generator that, given the current abstract state, should produce a suitable Command instance.

A generator that should produce an initial State instance that is usable by newSut to create a new system under test. The state returned by this generator is always checked with the initialPreCondition method before it is used.

A generator that should produce an initial State instance that is usable by newSut to create a new system under test. The state returned by this generator is always checked with the initialPreCondition method before it is used.

def initialPreCondition(state: State): Boolean

The precondition for the initial state, when no commands yet have run. This is used by ScalaCheck when command sequences are shrunk and the first state might differ from what is returned from genInitialState.

The precondition for the initial state, when no commands yet have run. This is used by ScalaCheck when command sequences are shrunk and the first state might differ from what is returned from genInitialState.

def newSut(state: State): Sut

Create a new Sut instance with an internal state that corresponds to the provided abstract state instance. The provided state is guaranteed to fulfill initialPreCondition, and newSut will never be called if canCreateNewSut is not true for the given state.

Create a new Sut instance with an internal state that corresponds to the provided abstract state instance. The provided state is guaranteed to fulfill initialPreCondition, and newSut will never be called if canCreateNewSut is not true for the given state.

Concrete methods

def commandSequence(head: Command, snd: Command, rest: Command*): Command

A command that runs a sequence of other commands. All commands (and their post conditions) are executed even if some command fails. Note that you probably can't use this method if you're testing in parallel (threadCount larger than 1). This is because ScalaCheck regards each command as atomic, even if the command is a sequence of other commands.

A command that runs a sequence of other commands. All commands (and their post conditions) are executed even if some command fails. Note that you probably can't use this method if you're testing in parallel (threadCount larger than 1). This is because ScalaCheck regards each command as atomic, even if the command is a sequence of other commands.

final def property(threadCount: Int, maxParComb: Int): Prop

A property that can be used to test this Commands specification.

A property that can be used to test this Commands specification.

The parameter threadCount specifies the number of commands that might be executed in parallel. Defaults to one, which means the commands will only be run serially for the same Sut instance. Distinct Sut instances might still receive commands in parallel, if the Test.Parameters.workers parameter is larger than one. Setting threadCount higher than one enables ScalaCheck to reveal thread-related issues in your system under test.

When setting threadCount larger than one, ScalaCheck must evaluate all possible command interleavings (and the end State instances they produce), since parallel command execution is non-deterministic. ScalaCheck tries out all possible end states with the Command.postCondition function of the very last command executed (there is always exactly one command executed after all parallel command executions). If it fails to find an end state that satisfies the postcondition, the test fails. However, the number of possible end states grows rapidly with increasing values of threadCount. Therefore, the lengths of the parallel command sequences are limited so that the number of possible end states don't exceed maxParComb. The default value of maxParComb is 1000000.

Override this to provide a custom Shrinker for your internal State. By default no shrinking is done for State.

Override this to provide a custom Shrinker for your internal State. By default no shrinking is done for State.