TestCenter Reference
BDD.py
Go to the documentation of this file.
1
#
2
# Copyright 2013, MeVis Medical Solutions AG
3
#
4
# The user may use this file in accordance with the license agreement provided with
5
# the Software or, alternatively, in accordance with the terms contained in a
6
# written agreement between the user and MeVis Medical Solutions AG.
7
#
8
# For further information use the contact form at https://www.mevislab.de/contact
9
#
10
11
"""Tools for writing human readable, behavioral tests.
12
13
The functions, decorators and classes defined in this module enable
14
you to write tests describing the desired behavior of a MeVisLab
15
module (or any other Python object).
16
17
A typical behavioral test looks like this:
18
19
def TEST_a_behavioral_test():
20
Given().a_precondition(). \
21
When().you_do_something(). \
22
Then().something_happens()
23
24
i.e. it is the concatenation of several function calls, or, in other words,
25
it is a sentence consisting of a Given clause, a When clause, and a Then
26
clause.
27
28
Given(), When(), and Then() are predefined functions marking the start of
29
the Given clause (and of the whole sentence), the When clause, and the Then
30
clause, respectively.
31
32
There is another predefined function, And(), which can be used to concatenate
33
several custom functions of the same type, e.g.
34
35
Given().precondition1(). \
36
And().precondition2(). \
37
[...]
38
39
The other functions are custom functions that are defined with the help
40
of three decorators: GivenClause, WhenClause, and ThenClause. (The decorators
41
add the decorated functions to the context class so that they can be called
42
as member functions.)
43
44
The Given() function creates and returns a context object for the test. All
45
other functions are member functions of this context object. These functions
46
also return the context object. This allows arbitrary chaining of those
47
functions. By adding attributes to the context object we can pass arbitrary
48
state from one function to the next.
49
50
See ExampleBDDTestCase in MeVisLab/Examples for an example.
51
52
For more information on Behavior Driven Development (BDD) check the Internet.
53
54
If you need a more powerful BDD-style language then have a look at one of the
55
existing Python BDD modules like behave, freshen, lettuce, etc.
56
"""
57
from
builtins
import
object
58
59
import
functools
60
61
from
TestSupport
import
Logging
62
63
64
def
Given
():
65
"""Initiates a sentence describing a desired behavior.
66
67
Creates and returns the context object for the test.
68
"""
69
return
_BDDContext
()
70
71
def
GivenClause
(func):
72
"""Decorator for defining a Given clause.
73
74
The first argument that is passed to the decorated function is the
75
context object. Custom parameters are passed to the decorated
76
function after the context object.
77
78
The decorated function always returns the context object.
79
80
Example:
81
@GivenClause
82
def a_precondition(testContext):
83
# perform the setup of the test, e.g. by parameterizing a TestPattern
84
# module
85
"""
86
return
_BDDClause(
'Given'
)(func)
87
88
def
WhenClause
(func):
89
"""Decorator for defining a When clause.
90
91
The first argument that is passed to the decorated function is the
92
context of the test case. Custom parameters are passed to the decorated
93
function after the context.
94
95
The decorated function always returns the context object.
96
97
Example:
98
@WhenClause
99
def you_do_something(testContext):
100
# do whatever shall result in a certain behavior, e.g. touch a field
101
"""
102
return
_BDDClause(
'When'
)(func)
103
104
def
ThenClause
(func):
105
"""Decorator for defining a Then clause.
106
107
The first argument that is passed to the decorated function is the
108
context of the test case. Custom parameters are passed to the decorated
109
function after the context.
110
111
The decorated function always returns the context object.
112
113
Example:
114
@ThenClause
115
def something_happens(testContext):
116
# check for the expected behavior, e.g. by comparing a field value
117
# with an expected value
118
"""
119
return
_BDDClause(
'Then'
)(func)
120
121
122
# Internal stuff
123
124
class
_BDDContext
(object):
125
"""Context of a BDD test case.
126
127
Instances of this class are created with Given(). All functions defined
128
with the clause decorators are added to _BDDContext.
129
"""
130
131
def
__init__
(self):
132
self.
_state
_state =
'Given'
133
134
def
And
(self):
135
"""Conjunction for joining two clauses of the same type.
136
137
This method does nothing except returning the context. It is merely
138
syntactic sugar for joining two clauses of the same type, i.e. two
139
Given clauses, two When clauses, or two Then clauses.
140
"""
141
return
self
142
143
def
With
(self):
144
"""Conjunction for joining two clauses of the same type.
145
146
This method does nothing except returning the context. It is merely
147
syntactic sugar for joining two clauses of the same type, i.e. two
148
Given clauses, two When clauses, or two Then clauses.
149
"""
150
return
self
151
152
def
When
(self):
153
"""Conjunction for marking the start of the When part.
154
155
This method starts the When part of the sentence describing the
156
desired behavior. It returns the context.
157
"""
158
self.
_state
_state =
'When'
159
return
self
160
161
def
Then
(self):
162
"""Conjunction for marking the start of the Then part.
163
164
This method starts the Then part of the sentence describing the
165
desired behavior. It returns the context.
166
"""
167
self.
_state
_state =
'Then'
168
return
self
169
170
def
__getattr__
(self, name):
171
"""Returns Given/When/Then method corresponding to @a name."""
172
prefix = self.
_state
_state +
'_'
173
if
not
name.startswith(prefix):
174
return
getattr(self, prefix + name)
175
else
:
176
raise
AttributeError(
'Attribute with name "%s" not found.'
% name)
177
178
def
_BDDClause(clauseType):
179
"""Internal decorator used for defining clauses of different types."""
180
def
func_wrapper(func):
181
@functools.wraps(func)
182
def
wrapper(self, *args, **kwargs):
183
func(self, *args, **kwargs)
184
return
self
185
setattr(_BDDContext, clauseType +
'_'
+ func.__name__, wrapper)
186
return
func_wrapper
TestSupport.BDD._BDDContext
Definition:
BDD.py:124
TestSupport.BDD._BDDContext.__init__
def __init__(self)
Definition:
BDD.py:131
TestSupport.BDD._BDDContext.When
def When(self)
Definition:
BDD.py:152
TestSupport.BDD._BDDContext._state
_state
Definition:
BDD.py:132
TestSupport.BDD._BDDContext.Then
def Then(self)
Definition:
BDD.py:161
TestSupport.BDD._BDDContext.With
def With(self)
Definition:
BDD.py:143
TestSupport.BDD._BDDContext.And
def And(self)
Definition:
BDD.py:134
TestSupport.BDD._BDDContext.__getattr__
def __getattr__(self, name)
Definition:
BDD.py:170
TestSupport.BDD.WhenClause
def WhenClause(func)
Definition:
BDD.py:88
TestSupport.BDD.Given
def Given()
Definition:
BDD.py:64
TestSupport.BDD.ThenClause
def ThenClause(func)
Definition:
BDD.py:104
TestSupport.BDD.GivenClause
def GivenClause(func)
Definition:
BDD.py:71
MeVisLab
Standard
Modules
Scripts
python
TestSupport
BDD.py
Generated by
1.9.1