While events can be sent to an interpreter using its
queue() method, it can be very convenient
to define and store scenarios, ie. sequences or traces of events, that can control the execution of a statechart.
Such scenarios are called stories in sismic, and can be used to accurately reproduce the execution of a statechart. They are also very instrumental for testing statecharts.
sismic.stories provides the building bricks to automate statechart execution.
The key concept of this module is the notion of story, which is a reproducible sequence of
events and pauses that control a statechart interpreter.
For our running elevator example, a story may encode things like “first select the 4th floor, then
wait 5 seconds, then select the 2th floor, then wait for another 10 seconds”.
This would look as follows:
from sismic.stories import Story, Pause, Event story = Story() story.append(Event('floorSelected', floor=4)) story.append(Pause(5)) story.append(Event('floorSelected', floor=2)) story.append(Pause(10))
For syntactical convenience, the same story can also be written more compactly using a Python iterable:
story = Story([Event('floorSelected', floor=4), Pause(5), Event('floorSelected', floor=2), Pause(10)])
# ... (assume that some interpreter has been created for our elevator statechart) assert isinstance(interpreter, Interpreter) story.tell(interpreter) print(interpreter.time, interpreter.context.get('current'))
After having told the story to the interpreter, we observe that 15 seconds have passed, and the elevator has moved to the ground floor.
While telling a whole story at once can be convenient, it is sometimes interesting to tell the story step by step.
tell_by_step() returns a generator that yields the object (either a pause or an event)
that was told to the interpreter, and the result of calling
# Recreate the interpreter interpreter = Interpreter(statechart) for told, macrosteps in story.tell_by_step(interpreter): print(interpreter.time, told, interpreter.context.get('current'))
0 Event('floorSelected', floor=4) 4 5 Pause(5) 4 5 Event('floorSelected', floor=2) 2 15 Pause(10) 0
sismic.stories contains several helper methods to write stories.
We expect this module to quickly growth and to provide many ways to automatically generate stories.
Currently, the module contains the following helpers:
random_stories_generator(items: typing.Sequence[typing.Union[sismic.model.events.Event, sismic.stories.Pause]], length: int = None, number: int = None) → typing.Generator[[sismic.stories.Story, NoneType], NoneType]
A generator that returns random stories whose elements come from items. Parameter items can be any iterable containing events and/or pauses.
- items – Items to pick from
- length – Length of the story, or len(items)
- number – number of stories to generate (None = infinite)
An infinite Story generator
story_from_trace(trace: typing.Iterable[sismic.model.steps.MacroStep]) → sismic.stories.Story
Return a story that is built upon the given trace (a list of macro steps).
The story is composed of the same pauses and the same events than the ones that generated the given trace. The use case is when you want to reproduce the scenario of an observed behavior.
Notice that internal events are ignored.
Parameters: trace – A list of MacroStep instances. Returns: A story