org.jwalk.core
Class StateSpaceWalker

java.lang.Object
  extended by org.jwalk.JWalker
      extended by org.jwalk.core.ClassInspector
          extended by org.jwalk.core.ProtocolWalker
              extended by org.jwalk.core.StateSpaceWalker
All Implemented Interfaces:
java.lang.Runnable

public class StateSpaceWalker
extends ProtocolWalker

StateSpaceWalker exercises all the high-level states and transitions of the test class. A StateSpaceWalker explores the high-level states of the test class, and all transition paths of increasing length, starting in each of the states. It has a more abstract view of state than an AlgebraWalker, but exercises more transitions, corresponding to the n-switch cover.

Version:
1.0
Author:
Anthony Simons

Field Summary
protected  java.util.List<java.lang.reflect.Method> predicates
          The subset of methods that are state predicates.
protected  java.util.Map<java.lang.String,TestSequence> stateCover
          The map from state names to the state cover sequences.
protected  boolean stateFlag
          The missing states flag that, when set to true, indicates that states were expected, but not found during the probing cycle.
 
Fields inherited from class org.jwalk.core.ProtocolWalker
oracle, summary
 
Fields inherited from class org.jwalk.core.ClassInspector
constants, constructors, methods, testClass
 
Fields inherited from class org.jwalk.JWalker
channels, settings
 
Constructor Summary
StateSpaceWalker(Settings settings, Channels channels)
          Creates a StateSpaceWalker, using the settings and channels.
 
Method Summary
 int countActiveEdges(int cycle)
          Counts the number of active edges on a given test cycle.
 int countMaxStates()
          Counts the maximum possible number of high-level design states.
 long countPermutations()
          Counts the number of TestSequence permutations.
protected  void discoverStates()
          Estimates the high-level design states of the test class.
 void execute()
          Executes this StateSpaceWalker test strategy according to the settings.
protected  void executeProbeCycle(java.util.List<TestSequence> testSet, int cycle)
          Executes a probing cycle to determine whether new states were reached.
protected  void executeTestSeries()
          Executes a series of test cycles for multiple high-level states.
protected  java.util.List<TestSequence> firstCycle(java.lang.String stateKey)
          Creates the first test set placing the test object into a given state.
 java.util.Map<java.lang.String,TestSequence> getStateCover()
          Returns the map from state names to state cover sequences.
 java.util.List<java.lang.reflect.Method> getStatePredicates()
          Returns the list of state predicates for the test class.
 boolean hasMissingStates()
          Reports if there are still missing states after exploration.
protected  boolean isPrunable(TestSequence sequence)
          Reports whether a given TestSequence may be pruned.
 
Methods inherited from class org.jwalk.core.ProtocolWalker
ensureExecutable, executeTestCycle, firstCycle, makeGenerator, nextCycle
 
Methods inherited from class org.jwalk.core.ClassInspector
classIsAbstract, classIsEnum, classIsInterface, classNotPublic, countConstants, countConstructors, countMethods, getConstants, getConstructors, getMethods, getTestClass, inspectProtocols
 
Methods inherited from class org.jwalk.JWalker
getChannels, getSettings, outOfMemory, run, userAborted
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

stateFlag

protected boolean stateFlag
The missing states flag that, when set to true, indicates that states were expected, but not found during the probing cycle. When set to false, indicates that sufficient states were found.


predicates

protected java.util.List<java.lang.reflect.Method> predicates
The subset of methods that are state predicates. These are methods with no argument, but a boolean result.


stateCover

protected java.util.Map<java.lang.String,TestSequence> stateCover
The map from state names to the state cover sequences. This is used to store the shortest sequences that reached each of the unique states discovered by this StateSpaceWalker.

Constructor Detail

StateSpaceWalker

public StateSpaceWalker(Settings settings,
                        Channels channels)
Creates a StateSpaceWalker, using the settings and channels.

Parameters:
settings - the test parameter settings to use.
channels - the call-back channels to report on.
Method Detail

hasMissingStates

public boolean hasMissingStates()
Reports if there are still missing states after exploration.

Returns:
true if more states were expected, but not found.

countMaxStates

public int countMaxStates()
Counts the maximum possible number of high-level design states. This is based on the number of state predicates in the test class. If there are none, there is one Default state. If there are n state predicates, there are 2^n possible states. In practice, there may be fewer actual states, if the predicates are not independent.

Returns:
the maximum number of high-level design states.

getStateCover

public java.util.Map<java.lang.String,TestSequence> getStateCover()
Returns the map from state names to state cover sequences. Only valid after this StateSpaceWalker has discovered some states.

Returns:
the map from state names to state cover sequences.

getStatePredicates

public java.util.List<java.lang.reflect.Method> getStatePredicates()
Returns the list of state predicates for the test class. Only valid after this StateSpaceWalker has discovered the test class's state predicates.

Returns:
the list of state predicates.

countPermutations

public long countPermutations()
Counts the number of TestSequence permutations. This is the maximum number of permutations of the test class's transitions, summed over all the states in its state cover, for the given depth of exploration. The effectiveness of any test strategy may be judged by how many fewer paths were actually explored than this theoretical maximum. Only valid after this StateSpaceWalker has inspected the test class.

Overrides:
countPermutations in class ClassInspector
Returns:
the number of TestSequence permutations.

countActiveEdges

public int countActiveEdges(int cycle)
Counts the number of active edges on a given test cycle. This is the maximum number of active edges that could be considered by the test strategy (before pruning is taken into account). Each test cycle only considers one state, so cycle 0 always has one active edge. Subsequent cycles grow edges in the power of the method-count. The test cycle number is in the range 0..n. If the cycle parameter is given a value outside this range, returns 0. Only valid after this StateSpaceWalker has inspected the test class.

Overrides:
countActiveEdges in class ClassInspector
Parameters:
cycle - the test cycle number, 0..n.
Returns:
the number of active edges on a given test cycle.

isPrunable

protected boolean isPrunable(TestSequence sequence)
Reports whether a given TestSequence may be pruned. When probing all high-level states, paths terminating in an exception or entering a previously visited concrete state are pruned. When testing from each design state, only paths terminating in an exception are pruned.

Overrides:
isPrunable in class ProtocolWalker
Parameters:
sequence - the TestSequence being evaluated.
Returns:
true if the TestSequence may be pruned by one of the above rules.

firstCycle

protected java.util.List<TestSequence> firstCycle(java.lang.String stateKey)
Creates the first test set placing the test object into a given state. Instead of starting with the initial construction of the test object, state-based testing starts in each high-level state, and later extends this with the n-switch transition cover. StateSpaceWalker executes a test series for each high-level state. This method therefore returns a singleton test set, containing the state cover sequence that reaches the requested state.

Parameters:
stateKey - the name of the state.
Returns:
the initial test set, a singleton sequence, that will drive the test object into the named state.

executeProbeCycle

protected void executeProbeCycle(java.util.List<TestSequence> testSet,
                                 int cycle)
                          throws PermissionException,
                                 GeneratorException,
                                 ExecutionException
Executes a probing cycle to determine whether new states were reached. If any reached state has not been seen before, adds the name of this state and the state cover sequence to the state cover map.

Parameters:
testSet - the current test set.
cycle - the test cycle number.
Throws:
GeneratorException - if any constructor or method argument value could not be synthesised. A CustomGenerator must be provided that is capable of synthesising values of the argument type.
ExecutionException - if any constructor or method could not be invoked, for reasons of visibility, security or bad arguments, or if it is detected that a constructor or method behaves randomly.
PermissionException - if the loaded test class, or any custom generator, could not be instantiated, either for reasons of security, or visibility, or because it was abstract, or an interface.

discoverStates

protected void discoverStates()
                       throws PermissionException,
                              GeneratorException,
                              ExecutionException
Estimates the high-level design states of the test class. Determines which of the test class's methods are state predicates, then explores all algebraic constructions to find new concrete states and evaluates each of these using all state predicates. Detects one new high-level state for each distinct boolean product outcome.

Throws:
GeneratorException - if any constructor or method argument value could not be synthesised. A CustomGenerator must be provided that is capable of synthesising values of the argument type.
ExecutionException - if any constructor or method could not be invoked, for reasons of visibility, security or bad arguments, or if it is detected that a constructor or method behaves randomly.
PermissionException - if the loaded test class, or any custom generator, could not be instantiated, either for reasons of security, or visibility, or because it was abstract, or an interface.

executeTestSeries

protected void executeTestSeries()
                          throws PermissionException,
                                 GeneratorException,
                                 ExecutionException
Executes a series of test cycles for multiple high-level states. Executes a series of test cycles, starting with the state cover prefix for each high-level state, and continuing with longer transition paths in subsequent cycles, up to the maximum requested transition path depth. At the end of the series, dispatches a SummaryReport to the registered listeners. May also read from, and write to an Oracle, if the settings requested validation of the results.

Overrides:
executeTestSeries in class ProtocolWalker
Throws:
GeneratorException - if any constructor or method argument value could not be synthesised. A CustomGenerator must be provided that is capable of synthesising values of the argument type.
ExecutionException - if any constructor or method could not be invoked, for reasons of visibility, security or bad arguments, or if it is detected that a constructor or method behaves randomly.
PermissionException - if the loaded test class, or any custom generator, could not be instantiated, either for reasons of security, or visibility, or because it was abstract, or an interface.

execute

public void execute()
             throws PermissionException,
                    GeneratorException,
                    ExecutionException
Executes this StateSpaceWalker test strategy according to the settings. If the Modality is INSPECT, extracts the public constructor and method interface of the test class and then dynamically detects the high-level design states of the test class. If the Modality is EXPLORE, also explores all permutations of methods, starting in each design state, to the requested path depth. If the Modality is VALIDATE, also validates the outcomes of every test using an Oracle.

Overrides:
execute in class ProtocolWalker
Throws:
GeneratorException - if any constructor or method argument value could not be synthesised. A CustomGenerator must be provided that is capable of synthesising values of the argument type.
ExecutionException - if any constructor or method could not be invoked, for reasons of visibility, security or bad arguments, or if it is detected that a constructor or method behaves randomly.
PermissionException - if the loaded test class, or any custom generator, could not be instantiated, either for reasons of security, or visibility, or because it was abstract, or an interface.