6 """Something asserted to be true during the test.
8 A given condition may be used as a precondition or a
12 """Called with a key and a state. True if the condition is met."""
16 """The affect an action will perform."""
19 """Called with a key and a state.
21 The effect modifies the state as appropriate."""
24 """Actions are the operations that will be permuted into test cases.
26 Each action has a collection of preconditions and postconditions
27 that will be evaluated for checking input and output state for the
30 Action.preconditions is the collection of conditions that must all
31 be true upon input to the action. If any condition is not true,
32 the effect is not executed and the action state is considered
35 Action.effect is the callable that is expected to alter the state
36 to satisfy the postconditions of the action.
38 Action.postconditions is the collection of conditions that must
39 all be true after the effect of the action completes.
49 """The name of this action (default derived from class name)"""
50 n = self.__class__.__name__
51 return n[0].lower() + n[1:]
54 """The driver "performs" the test."""
57 """Initialize and return the state for a test."""
61 """Invoked with the sequence of tests before any are run."""
64 """Invoked with the sequence of actions in a single test
65 before it is performed."""
68 """Invoked when before starting an action."""
71 """Invoked after the action is performed."""
74 """Invoked at the end of a sequence of tests."""
77 """Invoked with the sequence of tests after all of them are run."""
79 def runTest(actions, driver, duplicates=3, length=4):
80 """Run a test with the given collection of actions and driver.
82 The optional argument `duplicates' specifies how many times a
83 given action may be duplicated in a sequence.
85 The optional argument `length` specifies how long each test
89 instances = itertools.chain(*itertools.repeat([a()
for a
in actions],
91 tests = set(itertools.permutations(instances, length))
92 driver.preSuite(tests)
93 for seq
in sorted(tests):
94 state = driver.newState()
95 driver.startSequence(seq)
98 haserror =
not all(p(state)
for p
in a.preconditions)
102 haserror =
not all(p(state)
for p
in a.postconditions)
105 driver.endAction(a, state, haserror)
106 driver.endSequence(seq, state)
107 driver.postSuite(tests)
109 def findActions(classes):
110 """Helper function to extract action subclasses from a collection
114 for __t
in (t
for t
in classes
if isinstance(type,
type(t))):
115 if Action
in __t.__mro__
and __t != Action
and __t.enabled: