brine-dsl 0.7.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/LICENSE +1 -1
- data/README.adoc +29 -0
- data/brine-dsl.gemspec +5 -5
- data/docs/build.gradle +1 -1
- data/docs/cookbook.html +48 -40
- data/docs/guide.html +185 -119
- data/docs/index.html +18 -4
- data/docs/specs.html +227 -1
- data/docs/src/cookbook.adoc +57 -40
- data/docs/src/guide.adoc +227 -133
- data/docs/src/index.adoc +15 -3
- data/docs/src/specs.adoc +11 -0
- data/features/assignment/parameter.feature +20 -0
- data/features/assignment/random.feature +25 -0
- data/features/assignment/response_attribute.feature +33 -0
- data/features/assignment/timestamp.feature +33 -0
- data/lib/brine/cleaner_upper.rb +55 -16
- data/lib/brine/coercer.rb +55 -5
- data/lib/brine/rest_steps.rb +20 -39
- data/lib/brine/step_definitions/assignment.rb +33 -5
- data/lib/brine.rb +13 -8
- metadata +11 -3
- data/README.md +0 -7
data/docs/src/guide.adoc
CHANGED
@@ -3,12 +3,14 @@ Matt Whipple <http://github.com/mwhipple[@mwhipple]>
|
|
3
3
|
:description: The User Guide for using the Brine REST Testing DSL
|
4
4
|
:keywords: Brine, Cucumber, REST, DSL
|
5
5
|
:grave: `
|
6
|
+
:response_attribute: (body|status|headers)
|
6
7
|
|
7
8
|
Cucumber DSL for testing REST APIs
|
8
9
|
|
9
10
|
== Introduction
|
10
11
|
|
11
12
|
=== Motivation
|
13
|
+
|
12
14
|
REpresentational State Transfer APIs expose their functionality
|
13
15
|
through combinations of fairly coarse primitives that generally
|
14
16
|
revolve around the use of transferring data in a standard exchange
|
@@ -22,6 +24,7 @@ integrated into Cucumber, where Cucumber provides a test-oriented
|
|
22
24
|
framework for DSL creation.
|
23
25
|
|
24
26
|
=== Sample Usage
|
27
|
+
|
25
28
|
The general usage pattern revolves around construction of a request
|
26
29
|
and performing assertions against the received response.
|
27
30
|
|
@@ -42,39 +45,42 @@ And the value of the response body is including:
|
|
42
45
|
----
|
43
46
|
|
44
47
|
=== Key Features
|
48
|
+
|
45
49
|
Variable Binding/Expansion::
|
46
|
-
In cases where dynamic data is in the response or is desired for the
|
47
|
-
request, then values can be bound to identifiers which can then be
|
48
|
-
expanded using http://mustache.github.io[Mustache] templates in your
|
49
|
-
feature files.
|
50
|
+
In cases where dynamic data is in the response or is desired for the
|
51
|
+
request, then values can be bound to identifiers which can then be
|
52
|
+
expanded using http://mustache.github.io[Mustache] templates in your
|
53
|
+
feature files.
|
50
54
|
|
51
55
|
Type Transforms::
|
52
|
-
Different types of data can be expressed directly in the feature files
|
53
|
-
or expanded into variables by using the appropriate syntax for that
|
54
|
-
type.
|
56
|
+
Different types of data can be expressed directly in the feature files
|
57
|
+
or expanded into variables by using the appropriate syntax for that
|
58
|
+
type.
|
55
59
|
|
56
60
|
Type Coercion::
|
57
|
-
Related to transforms, a facility to coerce types is also provided. This
|
58
|
-
more intelligent comparison of inputs which have been transformed to a
|
59
|
-
richer data type with those that have not been transformed (normally strings).
|
60
|
-
As an example comparing a date/time value with a string will attempt to parse
|
61
|
-
the string to a date/time so that the values can be compared using the proper
|
61
|
+
Related to transforms, a facility to coerce types is also provided. This
|
62
|
+
allows more intelligent comparison of inputs which have been transformed to a
|
63
|
+
richer data type with those that have not been transformed (normally strings).
|
64
|
+
As an example comparing a date/time value with a string will attempt to parse
|
65
|
+
the string to a date/time so that the values can be compared using the proper
|
66
|
+
semantics.
|
62
67
|
|
63
68
|
<<_resource_cleanup>>::
|
64
|
-
Tests are likely to create resources which should then be cleaned up,
|
65
|
-
restoring the pre-test state of the system: steps to facilitate this
|
66
|
-
are provided.
|
69
|
+
Tests are likely to create resources which should then be cleaned up,
|
70
|
+
restoring the pre-test state of the system: steps to facilitate this
|
71
|
+
are provided.
|
67
72
|
|
68
73
|
Authentication::
|
69
|
-
Presently OAuth2 is supported to issue authenticated requests during a
|
70
|
-
test (likely using a feature `Background`).
|
74
|
+
Presently OAuth2 is supported to issue authenticated requests during a
|
75
|
+
test (likely using a feature `Background`).
|
71
76
|
|
72
77
|
Request Construction and Response Assertion Step Definitions::
|
73
|
-
The previous features combined with the library of provide steps should
|
74
|
-
cover all of the functionality needed to exercise and validate all of
|
75
|
-
the functionality exposed by your REST API.
|
78
|
+
The previous features combined with the library of provide steps should
|
79
|
+
cover all of the functionality needed to exercise and validate all of
|
80
|
+
the functionality exposed by your REST API.
|
76
81
|
|
77
82
|
== Installation
|
83
|
+
|
78
84
|
Brine is published as `brine-dsl` on rubygems, the page for which is
|
79
85
|
at https://rubygems.org/gems/brine-dsl. The latest version and other
|
80
86
|
gem metadata can be viewed on that page. Brine can be used by
|
@@ -104,12 +110,15 @@ feature files should be able to be written and executed without
|
|
104
110
|
requiring any additional ruby code.
|
105
111
|
|
106
112
|
== Tutorial
|
113
|
+
|
107
114
|
We'll write some tests against http://myjson.com/api
|
108
|
-
(selected fairly arbitrary from the list at
|
115
|
+
(selected fairly arbitrary from the list at
|
116
|
+
https://github.com/toddmotto/public-apis).
|
109
117
|
The API is being explored for the sake of this tutorial,
|
110
118
|
which also serves to bolster this library to support the effort.
|
111
119
|
|
112
120
|
=== Selecting a ROOT_URL
|
121
|
+
|
113
122
|
Brine expects steps to use relative URLs. The feature files specify
|
114
123
|
the behavior of an API (or multiple APIs), while the root of the
|
115
124
|
URLs define where that API is, so this is a natural mapping.
|
@@ -122,19 +131,23 @@ For simple cases where all tests are to be run against the same root,
|
|
122
131
|
the root url can be specified with the environment variable `ROOT_URL`,
|
123
132
|
such as `ROOT_URL=https://api.myjson.com/ cucumber`, or letting `rake`
|
124
133
|
take care of this for you such as:
|
134
|
+
|
125
135
|
[source,ruby]
|
126
136
|
----
|
127
137
|
Cucumber::Rake::Task.new do
|
128
138
|
ENV['ROOT_URL'] = 'https://api.myjson.com/'
|
129
139
|
end
|
130
140
|
----
|
141
|
+
|
131
142
|
which could then be called with `rake cucumber`. The rake approach
|
132
143
|
can be extended for different tasks for each environment, each
|
133
144
|
of which sets the appropriate environment variables allowing the
|
134
|
-
test code itself to follow
|
145
|
+
test code itself to follow
|
146
|
+
https://12factor.net/config[Twelve-Factor App guidelines]
|
135
147
|
where Rake provides sugary convenience.
|
136
148
|
|
137
149
|
=== A Basic GET
|
150
|
+
|
138
151
|
Most tests will involve some form of issuing requests and performing assertions
|
139
152
|
on the responses. Let's start with a simple version of that pattern,
|
140
153
|
testing the response status from a GET request.
|
@@ -145,9 +158,10 @@ include::../../tutorial/missing.feature[]
|
|
145
158
|
----
|
146
159
|
|
147
160
|
=== A Write Request
|
161
|
+
|
148
162
|
For POST, PATCH and PUT requests you'll normally want to include a request body.
|
149
|
-
To support this, additional data can be added to the requests before they are
|
150
|
-
(see <<_request_construction>>).
|
163
|
+
To support this, additional data can be added to the requests before they are
|
164
|
+
sent (see <<_request_construction>>).
|
151
165
|
|
152
166
|
[source,gherkin]
|
153
167
|
----
|
@@ -155,6 +169,7 @@ include::../../tutorial/post_status.feature[]
|
|
155
169
|
----
|
156
170
|
|
157
171
|
=== Test Response Properties
|
172
|
+
|
158
173
|
The API that was chosen for testing returns the link to the created resource
|
159
174
|
which is based off of a generated id. That means that the exact response cannot
|
160
175
|
be verified, but instead property based testing can be done to verify that the
|
@@ -168,6 +183,7 @@ include::../../tutorial/post_matching.feature[]
|
|
168
183
|
|
169
184
|
////
|
170
185
|
=== Known Response Data
|
186
|
+
|
171
187
|
One of the simplest and most obvious things to test for is that the response
|
172
188
|
contains data for which exact values are expected. Continuing from above we
|
173
189
|
can check that the response body returns the fields that we provided.
|
@@ -179,100 +195,131 @@ include::../../tutorial/post_including.feature[]
|
|
179
195
|
////
|
180
196
|
|
181
197
|
== Environment Variables
|
182
|
-
|
198
|
+
|
199
|
+
Some Brine behavior can be tuned by passing it appropriate environment
|
200
|
+
variables, listed here.
|
183
201
|
|
184
202
|
`BRINE_LOG_HTTP`::
|
185
|
-
Output HTTP traffic to stdout. Any truthy value will result in request and
|
186
|
-
metadata being logged, a value of `DEBUG` (case insensitive) will
|
203
|
+
Output HTTP traffic to stdout. Any truthy value will result in request and
|
204
|
+
response metadata being logged, a value of `DEBUG` (case insensitive) will
|
205
|
+
also log the bodies.
|
187
206
|
|
188
207
|
`BRINE_LOG_BINDING`::
|
189
|
-
Log values as they are assigned to variables in Brine steps.
|
208
|
+
Log values as they are assigned to variables in Brine steps.
|
190
209
|
|
191
210
|
== Language Conventions
|
211
|
+
|
192
212
|
=== The use of ``{grave}``s
|
213
|
+
|
193
214
|
Backticks/grave accents are used as _parameter delimiters_. It is perhaps
|
194
|
-
most helpful to think of them in those explicit terms rather than thinking of
|
195
|
-
as an alternate _quote_ construct. In particular quoting implies that the
|
196
|
-
value is a string value, while the step transforms allow for
|
215
|
+
most helpful to think of them in those explicit terms rather than thinking of
|
216
|
+
them as an alternate _quote_ construct. In particular quoting implies that the
|
217
|
+
parameter value is a string value, while the step transforms allow for
|
218
|
+
alternative data types.
|
197
219
|
|
198
|
-
``{grave}``s were chosen as they are less common than
|
199
|
-
|
200
|
-
quoting within paremeter values while hopefully avoiding the need for escape
|
201
|
-
(as used for argument transforms).
|
220
|
+
``{grave}``s were chosen as they are less common than many other syntactical
|
221
|
+
elements and also allow for the use of logically significant
|
222
|
+
quoting within paremeter values while hopefully avoiding the need for escape
|
223
|
+
artistry (as used for argument transforms).
|
202
224
|
|
203
225
|
== Selection and Assertion
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
226
|
+
|
227
|
+
As tests are generally concerned with performing assertions, a testing DSL
|
228
|
+
should be able to express the variety of assertions that may be needed. Because
|
229
|
+
these are likely to be numerous, it could easily lead to duplicated logic or
|
230
|
+
geometric growth of code due to the combinations of types of assertions and the
|
231
|
+
means to select the inputs for the assertion.
|
232
|
+
|
233
|
+
To avoid this issue the concepts of selection and assertion are considered
|
234
|
+
separate operations in Brine. Internally this corresponds to two steps: the
|
235
|
+
first assigns a selector;
|
236
|
+
the second passes the assertion to that selector which is responsible for
|
237
|
+
applying the assertion against the selected value(s). In standard step use this
|
238
|
+
will still be expressed as a single step,
|
213
239
|
and dynamic step definitions are used to split the work appropriately.
|
214
240
|
|
215
241
|
For example the step:
|
242
|
+
|
216
243
|
[source,gherkin]
|
217
244
|
----
|
218
245
|
Then the value of the response body is equal to `foo`
|
219
246
|
----
|
247
|
+
|
220
248
|
Will be split where the subject of the step (`the value of the response body`)
|
221
|
-
defines the selector and the predicate of the step
|
222
|
-
|
249
|
+
defines the selector and the predicate of the step
|
250
|
+
`is equal to {grave}foo{grave}` defines the assertion (which is translated to a
|
251
|
+
step such as `Then it is equal to {grave}foo{grave}`).
|
223
252
|
|
224
|
-
The result of this is that the assertion steps will always follow a pattern
|
225
|
-
resembles `the value of ...` and the predicate always
|
226
|
-
|
227
|
-
|
253
|
+
The result of this is that the assertion steps will always follow a pattern
|
254
|
+
where the subject resembles `the value of ...` and the predicate always
|
255
|
+
resembles `is ...`. Learning the selection phrases and the assertion phrases
|
256
|
+
and combining them should be a more efficient and flexible way to become
|
257
|
+
familiar with the language instead of focusing on the resulting combined steps.
|
228
258
|
|
229
259
|
The chosen approach sacrifices eloquence for the sake of consistency.
|
230
|
-
The predicate will always start with `is` which can lead to awkward language
|
231
|
-
`is including` rather than simply `includes`.
|
260
|
+
The predicate will always start with `is` which can lead to awkward language
|
261
|
+
such as `is including` rather than simply `includes`.
|
232
262
|
The consistency provides additional benefits such as consistent modification:
|
233
|
-
for instance `is not` can always be use for negation rather than working out the
|
234
|
-
phrasing for a more natural sounding step (let alone the logic).
|
263
|
+
for instance `is not` can always be use for negation rather than working out the
|
264
|
+
appropriate phrasing for a more natural sounding step (let alone the logic).
|
235
265
|
|
236
|
-
One of the secondary goals of this is that assertion step definitions should
|
237
|
-
write and modifiers (such as negation) should be provided for
|
238
|
-
|
266
|
+
One of the secondary goals of this is that assertion step definitions should
|
267
|
+
be very simple to write and modifiers (such as negation) should be provided for
|
268
|
+
free to those definitions.
|
269
|
+
As assertion definitions are likely to be numerous and potentially customized,
|
270
|
+
this should help optimize code economy.
|
239
271
|
|
240
272
|
=== Selection Modifiers
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
273
|
+
|
274
|
+
To pursue economical flexibility Brine steps attempt to balance step definitions
|
275
|
+
which accommodate variations while keeping the step logic and patterns fairly
|
276
|
+
simple. Selection steps in particular generally accept some parameters that
|
277
|
+
affect their behavior. This allows the relatively small number of selection
|
278
|
+
steps to provide the flexibility to empower the more numerous assertion steps.
|
245
279
|
|
246
280
|
==== Traversal
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
281
|
+
|
282
|
+
Selection steps can generally target the root of the object specified (such as
|
283
|
+
the response body) or some nodes within the object if it is a non-scalar value
|
284
|
+
(for instance a child of the response body). This is indicated in the
|
285
|
+
<<_selection,step reference selection steps>> by the `[$TRAVERSAL]` placeholder.
|
286
|
+
`child {grave}$EXPRESSION{grave}` or `children {grave}$EXPRESSION{grave}` can
|
287
|
+
optionally be inserted at the placeholder to select nested nodes as described
|
288
|
+
in <<_traversal_2>>.
|
252
289
|
|
253
290
|
==== Negation
|
254
|
-
The selectors also currently handle negation of the associated assertions.
|
255
|
-
This is potentially counter-intuitive but as previously mentioned the intent is that this
|
256
|
-
should ease the creation of assertions. If negation is added to a selector that it is expected that
|
257
|
-
the assertion will _fail_.
|
258
291
|
|
259
|
-
|
260
|
-
|
261
|
-
|
292
|
+
The selectors also currently handle negation of the associated assertions.
|
293
|
+
This is potentially counter-intuitive but as previously mentioned the intent is
|
294
|
+
that this should ease the creation of assertions. If negation is added to a
|
295
|
+
selector that it is expected that the assertion will _fail_.
|
296
|
+
|
297
|
+
Negation will be normally indicated in the
|
298
|
+
<<_selection,step reference selection steps>> by the presence
|
299
|
+
of the `[not]` placeholder. A similar placeholder may be used that is more
|
300
|
+
readable but leads to an equivalent inversion of the semantics of the statement.
|
301
|
+
To negate the step, the text within the ``[]``s should be inserted
|
262
302
|
in the indicated position.
|
263
303
|
|
264
304
|
[NOTE, caption='Future Versions']
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
305
|
+
|
306
|
+
Handling this in the selectors is (as mentioned) counter-intuitive and
|
307
|
+
unnecessarily couples the selector to the assertion. It is currently done for
|
308
|
+
practical reasons but is likely to be replaced in a future version after (or as
|
309
|
+
part of) the initial port of the library to another platform. When it is
|
310
|
+
replaced, all existing steps will remain supported through at least one more
|
311
|
+
major revision and most should (most should remain unchanged).
|
269
312
|
|
270
313
|
=== Chained Assertions
|
314
|
+
|
271
315
|
[WARNING, caption='Unsupported Feature']
|
316
|
+
|
272
317
|
Use at your own risk, this feature is *not presently supported*.
|
273
318
|
|
274
|
-
For anyone that likes to live on the (relative) edge or if this gathers notable
|
275
|
-
provides an implicit feature: after a value is
|
319
|
+
For anyone that likes to live on the (relative) edge or if this gathers notable
|
320
|
+
interest...the above also provides an implicit feature: after a value is
|
321
|
+
selected multiple assertions could be performed against it.
|
322
|
+
|
276
323
|
For instance:
|
277
324
|
|
278
325
|
[source,gherkin]
|
@@ -280,62 +327,91 @@ For instance:
|
|
280
327
|
Then the value of the response body is equal to `foo`
|
281
328
|
And it is of the type `String`
|
282
329
|
----
|
283
|
-
|
284
|
-
|
285
|
-
|
330
|
+
|
331
|
+
Though this may work in simple cases the present design is likely to produce
|
332
|
+
surprising results since some aspects (such as negation) are handled by the
|
333
|
+
selector so it would be inherited by the conjunctions even though it wouldn't
|
334
|
+
read that way.
|
286
335
|
|
287
336
|
== Traversal
|
288
|
-
The language exposed by Brine is flat but the data returned by the server is likely
|
289
|
-
to include deeper data structures such as objects and collections. To allow selection within
|
290
|
-
such structures a `traversal` language is embedded within some steps which will be indicated
|
291
|
-
by the use of the `TRAVERSAL` placeholder.
|
292
337
|
|
293
|
-
The
|
338
|
+
The language exposed by Brine is flat but the data returned by the server is
|
339
|
+
likely to include deeper data structures such as objects and collections. To
|
340
|
+
allow selection within such structures a `traversal` language is embedded within
|
341
|
+
some steps which will be indicated by the use of the `TRAVERSAL` placeholder.
|
342
|
+
|
343
|
+
The traversal language consists of a selected subset of
|
344
|
+
http://goessner.net/articles/JsonPath/[JsonPath].
|
294
345
|
|
295
346
|
[NOTE, caption='The Selected Subset']
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
347
|
+
|
348
|
+
The subset of JsonPath functionality has been chosen that is believed to support
|
349
|
+
all needed test cases without requiring deep familiarity with JsonPath. This may
|
350
|
+
lead to more numerous simple steps in place of fewer steps that use unsupported
|
351
|
+
expressions. Additionally Brine is intended to be ported to a range of platforms
|
352
|
+
and so only those steps outlined here will be supported across those platforms.
|
353
|
+
JsonPath expressions _not_ listed below will not be explicitly disallowed but
|
354
|
+
are not officially supported (will not be tested and will not be ported to
|
355
|
+
another platform if needed).
|
302
356
|
|
303
357
|
=== Cardinality
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
358
|
+
|
359
|
+
Each traversal expression will select _all_ matching nodes which is therefore
|
360
|
+
represented as a collection. Often, however, only a single node is expected or
|
361
|
+
desired. Therefore the traversal expression will also be accompanied by a phrase
|
362
|
+
which defines the expected cardinality, normally `child` vs. `children`.
|
363
|
+
`children` will _always_ return an array while `child` will return what would be
|
364
|
+
the first element in that array. `child` should be used when accessing a
|
365
|
+
specific node within the tree, while `children` should be used for what amounts
|
366
|
+
to a query across multiple nodes (such as testing the value of a field for every
|
367
|
+
element in a collection).
|
310
368
|
|
311
369
|
=== Expressions
|
370
|
+
|
312
371
|
`.$KEY`::
|
313
372
|
Access the `KEY` named child of the starting node. The leading `.` can be
|
314
|
-
omitted if at the start of an expression.
|
373
|
+
omitted if at the start of an expression.
|
374
|
+
|
375
|
+
`.[$INDEX]`::
|
376
|
+
Access the element of the array at index `INDEX`
|
377
|
+
|
378
|
+
`.[$FROM:$TO]`::
|
379
|
+
Access a slice of the array containing the elements at index `FROM` through
|
380
|
+
`TO` (including both limits).
|
315
381
|
|
316
382
|
== Resource Cleanup
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
383
|
+
|
384
|
+
All test suites should clean up after themselves as a matter of hygiene and to
|
385
|
+
help enforce test independence and reproducibility. This is particularly
|
386
|
+
important for this library given that it is likely the systems under test
|
387
|
+
are likely to remain running; accumulated uncleaned resources are at best a
|
388
|
+
nuisance to have to weed through and at worst raise some costs or other due to
|
389
|
+
heightened consumption of assorted resources (as opposed to more ephemeral test
|
390
|
+
environments).
|
391
|
+
|
392
|
+
Brine therefore provides mechanisms to assist in cleaning up those resources
|
393
|
+
which are created as part of a test run. A conceptual hurdle for this type of
|
394
|
+
functionality is that it is very unlikely to be part of the feature that is
|
395
|
+
being specified, and therefore should ideally not be part of the specification.
|
396
|
+
Depending on the functionality (and arguably the
|
397
|
+
https://www.martinfowler.com/articles/richardsonMaturityModel.html[maturity])
|
398
|
+
of the API, most or all of the cleanup can be automagically done based on
|
399
|
+
convention. There are tentative plans to support multiple techniques for
|
400
|
+
cleaning up resources based on how much can be implicitly
|
401
|
+
ascertained...though presently there exists only one.
|
330
402
|
|
331
403
|
=== Step indicating resource to DELETE
|
332
|
-
|
333
|
-
|
404
|
+
|
405
|
+
If the API supports DELETE requests to remove created resources but it is either
|
406
|
+
desirable or necessary to specify what those resource PATHS are, a step can be
|
407
|
+
used to indicate which resources should be DELETEd upon test completion.
|
334
408
|
|
335
409
|
_see <<_cleanup,Cleanup Step Definitions>>_
|
336
410
|
|
337
411
|
== Step Reference
|
412
|
+
|
338
413
|
=== Request Construction
|
414
|
+
|
339
415
|
link:specs.html#_request_construction[icon:cogs[] Specification]
|
340
416
|
|
341
417
|
The requests which are sent as part of a test are constructed using
|
@@ -343,47 +419,62 @@ a https://en.wikipedia.org/wiki/Builder_pattern[Builder].
|
|
343
419
|
|
344
420
|
`When a $METHOD is sent to {grave}$PATH{grave}`::
|
345
421
|
As every request to a REST API is likely to have a significant
|
346
|
-
HTTP `METHOD` and `PATH`, this step is considered required and is therefore
|
347
|
-
to send the built request. This should therefore be the *last* step for
|
348
|
-
given request that is being built.
|
422
|
+
HTTP `METHOD` and `PATH`, this step is considered required and is therefore
|
423
|
+
used to send the built request. This should therefore be the *last* step for
|
424
|
+
any given request that is being built.
|
349
425
|
|
350
426
|
`When the request body is assigned:`::
|
351
427
|
The multiline content provided will be assigned to the body of the request.
|
352
|
-
This will normally likely be the JSON representation of data.
|
428
|
+
This will normally likely be the JSON representation of data.
|
353
429
|
|
354
|
-
`When the request query parameter {grave}$PARAMETER{grave} is assigned
|
430
|
+
`When the request query parameter {grave}$PARAMETER{grave} is assigned
|
431
|
+
{grave}$VALUE{grave}`::
|
355
432
|
Assign `VALUE` to the request query `PARAMETER`.
|
356
|
-
The value will be URL encoded and the key/value pair appended to the URL using
|
357
|
-
the appropriate `?` or `&` delimiter.
|
358
|
-
The order of the parameters in the resulting URL should be considered
|
433
|
+
The value will be URL encoded and the key/value pair appended to the URL using
|
434
|
+
the appropriate `?` or `&` delimiter.
|
435
|
+
The order of the parameters in the resulting URL should be considered
|
436
|
+
undefined.
|
359
437
|
|
360
438
|
`When the request header {grave}$HEADER{grave} is assigned {grave}$VALUE{grave}`::
|
361
439
|
Assign `VALUE` to the request header `HEADER`.
|
362
|
-
Will overwrite any earlier value for the specified header, including earlier
|
440
|
+
Will overwrite any earlier value for the specified header, including earlier
|
441
|
+
steps or defaults.
|
363
442
|
|
364
443
|
=== Cleanup
|
444
|
+
|
365
445
|
`When a resouce is created at {grave}$PATH{grave}`::
|
366
|
-
Mark `PATH` as a resource to DELETE after the test is run.
|
446
|
+
Mark `PATH` as a resource to DELETE after the test is run.
|
447
|
+
See <<_resource_cleanup>>
|
367
448
|
|
368
449
|
=== Assignment
|
450
|
+
|
451
|
+
link:specs.html#_assignment[icon:cogs[] Specification]
|
452
|
+
|
369
453
|
`When {grave}$IDENTIFIER{grave} is assigned {grave}$VALUE{grave}`::
|
370
454
|
Assigns `VALUE` to `IDENTIFIER`.
|
371
455
|
|
372
456
|
`When {grave}$IDENTIFIER{grave} is assigned a random string`::
|
373
457
|
Assigns a random string (UUID) to `IDENTIFIER`.
|
374
|
-
This is particularly useful to assist with test isolation.
|
458
|
+
This is particularly useful to assist with test isolation.
|
375
459
|
|
376
460
|
`When {grave}$IDENTIFIER{grave} is assigned a timestamp`::
|
377
461
|
Assigns to `IDENTIFIER` a timestamp value representing the instant at
|
378
|
-
which the step was evaluated.
|
462
|
+
which the step was evaluated.
|
463
|
+
|
464
|
+
`When {grave}$IDENTIFIER{grave} is assigned the response {response_attribute} [$TRAVERSAL]`::
|
465
|
+
Assigns to `IDENTIFIER` the value extracted from the specified response
|
466
|
+
attribtute (at the optional traversal path).
|
379
467
|
|
380
468
|
=== Selection
|
469
|
+
|
381
470
|
link:specs.html#_selection[icon:cogs[] Specification]
|
382
471
|
|
383
472
|
_see <<_selection_and_assertion>>_
|
384
473
|
|
385
|
-
|
386
|
-
|
474
|
+
_TODO: Replace all the explicit attributes._
|
475
|
+
|
476
|
+
`Then the value of the response {response_attribute} is`::
|
477
|
+
Select the sepecified attribute of the current HTTP response.
|
387
478
|
|
388
479
|
`Then the value of the response body [$TRAVERSAL] is [not]`::
|
389
480
|
Select the value from the body of the response.
|
@@ -395,6 +486,7 @@ _see <<_selection_and_assertion>>_
|
|
395
486
|
Select all elements from the structure within the response body.
|
396
487
|
|
397
488
|
=== Assertion
|
489
|
+
|
398
490
|
link:specs.html#_assertion[icon:cogs[] Specification]
|
399
491
|
|
400
492
|
_see <<_selection_and_assertion>>_
|
@@ -409,13 +501,15 @@ _see <<_selection_and_assertion>>_
|
|
409
501
|
Assert that the current select value includes/is a superset of `VALUE`.
|
410
502
|
|
411
503
|
`Then it is empty`::
|
412
|
-
Assert that value is empty or null. Any type which is not testable for
|
413
|
-
(such as booleans or numbers) will always return false. Null is
|
414
|
-
value so that it can be treated as such for endpoints that
|
504
|
+
Assert that value is empty or null. Any type which is not testable for
|
505
|
+
emptiness (such as booleans or numbers) will always return false. Null is
|
506
|
+
treated as an empty value so that it can be treated as such for endpoints that
|
507
|
+
return null in place of empty collections, and non-null empty values can
|
508
|
+
easily be tested for using conjunction.
|
415
509
|
|
416
510
|
`Then it is of length {grave}$VALUE{grave}`::
|
417
511
|
Assert that the value exposes a length attribute and the value of that
|
418
|
-
attribute is `VALUE`.
|
512
|
+
attribute is `VALUE`.
|
419
513
|
|
420
514
|
`Then it is a valid {grave}$TYPE{grave}`::
|
421
515
|
Assert that the selected value is a valid instance of a `TYPE`. Presently this
|
data/docs/src/index.adoc
CHANGED
@@ -5,12 +5,24 @@ Matt Whipple <http://github.com/mwhipple[@mwhipple]>
|
|
5
5
|
|
6
6
|
Cucumber DSL for testing REST APIs
|
7
7
|
|
8
|
-
==
|
9
|
-
|
8
|
+
== Overview
|
9
|
+
|
10
|
+
The documentation should provide the background information to
|
11
|
+
get started using Brine and a framework for figuring out specific details.
|
12
|
+
The focus of guides will be on concepts and high level information while
|
13
|
+
more comprehensive and finer grained information will be provided by
|
14
|
+
specifications and source. Recipes will be provided for problems which
|
15
|
+
are common, interesting, or anything anyone wants to contribute :).
|
16
|
+
|
17
|
+
== Documents
|
10
18
|
|
11
19
|
link:guide.html[icon:book[] User Guide]::
|
12
20
|
A guide to writing specifications using the Brine provided DSL.
|
21
|
+
|
13
22
|
link:specs.html[icon:cogs[] Specification]::
|
14
23
|
The Gherkin specification for all of Brine's features.
|
24
|
+
|
15
25
|
link:cookbook.html[icon:cutlery[] Cookbook]::
|
16
|
-
Solutions to some problems which Brine does not solve directly.
|
26
|
+
Solutions to some problems which Brine does not solve directly.
|
27
|
+
|
28
|
+
_TODO: The current Cookbook name should be qualified to match its scope_
|
data/docs/src/specs.adoc
CHANGED
@@ -4,6 +4,7 @@ Matt Whipple <http://github.com/mwhipple[@mwhipple]>
|
|
4
4
|
:keywords: Brine, Cucumber, RESt, DSL
|
5
5
|
|
6
6
|
== Request Construction
|
7
|
+
|
7
8
|
gherkin::../../features/request_construction/basic.feature[spec.erb]
|
8
9
|
gherkin::../../features/request_construction/body.feature[spec.erb]
|
9
10
|
gherkin::../../features/request_construction/params.feature[spec.erb]
|
@@ -11,13 +12,23 @@ gherkin::../../features/request_construction/headers.feature[spec.erb]
|
|
11
12
|
gherkin::../../features/request_construction/clearing.feature[spec.erb]
|
12
13
|
|
13
14
|
== Resource Cleanup
|
15
|
+
|
14
16
|
gherkin::../../features/resource_cleanup/cleanup.feature[spec.erb]
|
15
17
|
|
18
|
+
== Assignment
|
19
|
+
|
20
|
+
gherkin::../../features/assignment/parameter.feature[spec.erb]
|
21
|
+
gherkin::../../features/assignment/random.feature[spec.erb]
|
22
|
+
gherkin::../../features/assignment/timestamp.feature[spec.erb]
|
23
|
+
gherkin::../../features/assignment/response_attribute.feature[spec.erb]
|
24
|
+
|
16
25
|
== Selection
|
26
|
+
|
17
27
|
gherkin::../../features/selectors/any.feature[spec.erb]
|
18
28
|
gherkin::../../features/selectors/all.feature[spec.erb]
|
19
29
|
|
20
30
|
== Assertion
|
31
|
+
|
21
32
|
gherkin::../../features/assertions/is_equal_to.feature[spec.erb]
|
22
33
|
gherkin::../../features/assertions/is_matching.feature[spec.erb]
|
23
34
|
gherkin::../../features/assertions/is_including.feature[spec.erb]
|