brine-dsl 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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]
|